美文网首页自动化美文共赏
Linux xargs 命令解析

Linux xargs 命令解析

作者: rollingstarky | 来源:发表于2021-12-09 20:23 被阅读0次

基本使用

xargs 是 Linux 系统中的一个命令行工具,它可以读取标准输入并将其作为参数构建新的命令并执行。
xargs 可以帮助 echormmkdir 等命令接收标准输入作为参数。

$ xargs mkdir
test1 test2
$ ls
test1  test2

比如执行 xargs mkdir 命令,输入 test1 test2 后回车,再按 CTRL-D 结束输入,等效于直接执行 mkdir test1 test2 命令。
xarg 读取了标准输入中的 test1 test2,并将它们作为参数传递给 mkdir 命令,组合成一个完整的 mkdir test1 test2 命令并执行。

实际上 xargs 很少用在上述交互式场景中,更多的是搭配管道符 |,通过前一个命令的输出构建新的命令。

$ echo test3 test4 test5 | xargs mkdir
$ ls
test1  test2  test3  test4  test5

|| xargs 的区别:

  • 管道符 | 是将左边命令的输出结果作为右边命令的输入值
  • | xargs 则可以将左边命令的输出结果作为右边命令的参数选项

find 与 xargs

xargs 最常见的搭配应该就是 find 命令了。即通过 find 查找特定的文件或目录,再将结果传递给 xargs,对找到的结果执行特定的操作。

如删除 /tmp 路径下最近两周内未做改动的文件:
find /tmp -type f -mtime +14 | xargs rm

有一点特别需要注意:默认情况下,xargs 从标准输入读取命令参数时,会以空格作为分隔符来识别多个选项。
而文件和目录的名字有时候也会包含空格,导致一个文件名被 xargs 识别为两个参数。

$ mkdir test\ 6
$ ls
'test 6'   test1   test2   test3   test4   test5
$ find . -type d | xargs rmdir
rmdir: failed to remove './test': No such file or directory
rmdir: failed to remove '6': No such file or directory
$ ls
'test 6'

更安全一点的做法是使用 -0 选项。-0 选项可以指定 xargs 在读取标准输入时使用 null 作为分隔符。而 find 命令的 -print0 选项同样可以将输出指定为使用 null 进行分割。

即将前面的命令替换为 find . -type d -print0 | xargs -0 rmdir

find 搭配 -exec 选项和搭配 xargs 命令的区别

find 命令可以使用其 -exec 选项对查找到的结果执行特定的操作。同样的需求 xargs 也可以实现。

比如需要删除当前目录下所有的 TXT 文件:

  • 使用 -execfind . -type f -name "*.txt" -exec rm {} \;
  • 使用 xargsfind . -type f -name "*.txt" | xargs rm

实际上两者的执行效率存在着很大的差距。
比如使用 for i in {1..100}; do touch $i.txt; done 命令创建 100 个 TXT 文件,再分别使用上述两个命令删除这些文件(用 time 命令计时),具体的效率如下:

$ for i in {1..100}; do touch $i.txt; done
$ ls
1.txt    18.txt  27.txt  36.txt  45.txt  54.txt  63.txt  72.txt  81.txt  90.txt
10.txt   19.txt  28.txt  37.txt  46.txt  55.txt  64.txt  73.txt  82.txt  91.txt
100.txt  2.txt   29.txt  38.txt  47.txt  56.txt  65.txt  74.txt  83.txt  92.txt
11.txt   20.txt  3.txt   39.txt  48.txt  57.txt  66.txt  75.txt  84.txt  93.txt
12.txt   21.txt  30.txt  4.txt   49.txt  58.txt  67.txt  76.txt  85.txt  94.txt
13.txt   22.txt  31.txt  40.txt  5.txt   59.txt  68.txt  77.txt  86.txt  95.txt
14.txt   23.txt  32.txt  41.txt  50.txt  6.txt   69.txt  78.txt  87.txt  96.txt
15.txt   24.txt  33.txt  42.txt  51.txt  60.txt  7.txt   79.txt  88.txt  97.txt
16.txt   25.txt  34.txt  43.txt  52.txt  61.txt  70.txt  8.txt   89.txt  98.txt
17.txt   26.txt  35.txt  44.txt  53.txt  62.txt  71.txt  80.txt  9.txt   99.txt
$ time find . -type f -name "*.txt" -exec rm {} \;
find . -type f -name "*.txt" -exec rm {} \;  0.05s user 0.02s system 104% cpu 0.060 total
$ for i in {1..100}; do touch $i.txt; done
$ time find . -type f -name "*.txt" | xargs rm
find . -type f -name "*.txt"  0.00s user 0.00s system 80% cpu 0.001 total
xargs rm  0.00s user 0.00s system 94% cpu 0.003 total

前者是 0.06,后者是 0.004。使用 xargs 的执行效率更高。

输出执行的命令

-t 选项可以把 xargs 拼接后执行的命令打印到终端窗口中。方便对脚本进行调试。

$ echo test1 test2 test3 | xargs -t mkdir
mkdir test1 test2 test3

输出命令并提示用户确认

-p 选项可以把 xargs 拼接后执行的命令打印出来,并等待用户进行确认。

$ ls | xargs -p rmdir
rmdir test1 test2 test3 ?...y

执行多个命令

借助 -I 选项可以令 xargs 同时执行多个命令。

$ cat foo.txt
one
two
three
$ cat foo.txt | xargs -I % sh -c 'echo %; mkdir %'
one
two
three
$ ls
foo.txt  one  three  two

常用实例

查找当前路径下所有的 PNG 图片并将它们归档到 images.tar.gz 压缩包中
$ find . -name "*.png" -type f -print0 | xargs -0 tar -cvzf images.tar.gz

获取当前系统中所有用户的用户名,以单行列表的形式输出

$ cut -d: -f1 < /etc/passwd | sort | xargs echo
_apt backup bin daemon games gnats irc landscape list lp mail man messagebus news nobody pollinate postgres proxy root sshd starky sync sys syslog systemd-network systemd-resolve systemd-timesync tcpdump tss uucp uuidd www-data

删除当前路径下名为 no_use 的文件
$ find . -name "no_use" -type f -print0 | xargs -0 rm -v -f

复制一个文件到多个路径下

$ ls
dest1  dest2  test_file
$ echo ./dest1/ ./dest2/ | xargs -n 1 cp -v ./test_file
'./test_file' -> './dest1/test_file'
'./test_file' -> './dest2/test_file'

上面例子中 xargs-n 1 选项非常重要。-n 选项用于指定 xargs 在将标准输入作为参数与命令拼接在一起时,参数的最大长度。

简单来说,当 -n 为 1 时,标准输入中以空格分割的每一项都与命令进行拼接,最终形成多条命令;当不存在 -n 1 时,标准输入中以空格分割的所有参数项直接与命令进行拼接,形成一条命令并执行。

$ echo ./dest1/ ./dest2/ | xargs -n 1 -t cp ./test_file
cp ./test_file ./dest1/
cp ./test_file ./dest2/
$ echo ./dest1/ ./dest2/ | xargs -t cp ./test_file
cp ./test_file ./dest1/ ./dest2/
cp: -r not specified; omitting directory './dest1/'
  • echo ./dest1/ ./dest2/ | xargs -n 1 cp ./test_file 等效于 cp ./test_file ./dest1/cp ./test_file ./dest2/ 两条命令
  • echo ./dest1/ ./dest2/ | xargs cp ./test_file 等效于 cp ./test_file ./dest1/ ./dest2/ 一条命令(语法是错的)

参考资料

Linux and Unix xargs command tutorial with examples
12 Practical Examples of Linux Xargs Command for Beginners

相关文章

  • Linux xargs 命令解析

    基本使用 xargs 是 Linux 系统中的一个命令行工具,它可以读取标准输入并将其作为参数构建新的命令并执行。...

  • Linux那点事-xargs命令详解

    Linux xargs 命令 xargs原理剖析及用法详解 1. 为什么需要xargs命令 1.1 管道|的缺陷 ...

  • xargs命令详解

    linux命令之xargs 1、xargs命令简介 xargs命令是给其他命令传递参数的一个过滤器,也是组合多个命...

  • Linux xargs 命令

    简介 xargs 是给命令传递参数的一个过滤器,也是组合多个命令的一个工具。 xargs 可以将管道或标准输入(s...

  • Linux:xargs命令

    有些命令只能以命令行参数的形式接受数据,无法通过stdin接受数据流,此时采用命令xargs,将标准输入数据转换成...

  • linux常用的命令笔记

    linux 查询命令:find / -type f -name "*.*" | xargs grep "关键字" ...

  • Linux自带一些命令简单使用

    在linux下解压在win下压缩的zip文件乱码解决 xargs命令的使用,这个命令是linux自带命令也就是说各...

  • 如何解压目录下的所有zip压缩文件

    使用find xargs命令 xargs命令详解,xargs与管道的区别

  • Linux xargs命令详解

    为什么要用xargs,问题的来源 在工作中经常会接触到xargs命令,特别是在别人写的脚本里面也经常会遇到,但是却...

  • linux命令-xargs使用

    git diff --name-only 67669e07b2f8cb1068cb068693170e61d34...

网友评论

    本文标题:Linux xargs 命令解析

    本文链接:https://www.haomeiwen.com/subject/bahffrtx.html