xargs
命令是可以将标准输入改变输出格式作为参数传递给其他命令,弥补有些命令(如 echo
,rm
等)不接受管道传参。
标准输入 默认 xargs
把多行转为一行:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 (base) root@ubuntu-studio:/workspace jinzhongxu/codes/py/test-debug/main.py jinzhongxu/codes/py/audio/server.py jinzhongxu/codes/py/audio/client.py jinzhongxu/codes/py/audio/record.py jinzhongxu/codes/py/pys/mymodule/utils/unzip.py jinzhongxu/codes/py/pys/mymodule/utils/TimeStamps.py jinzhongxu/codes/py/pys/mymodule/utils/ipynb.py jinzhongxu/codes/py/pys/mymodule/cv/gif.py jinzhongxu/codes/py/pys/mymodule/cv/image_sam_annotate.py jinzhongxu/codes/py/pys/mymodule/cv/bbox_video.py jinzhongxu/codes/py/pys/mymodule/cv/video.py jinzhongxu/codes/py/pys/mymodule/cv/image.py jinzhongxu/codes/py/pys/mymodule/cv/video_cut.py (base) root@ubuntu-studio:/workspace jinzhongxu/codes/py/test-debug/main.py jinzhongxu/codes/py/audio/server.py jinzhongxu/codes/py/audio/client.py jinzhongxu/codes/py/audio/record.py jinzhongxu/codes/py/pys/mymodule/utils/unzip.py jinzhongxu/codes/py/pys/mymodule/utils/TimeStamps.py jinzhongxu/codes/py/pys/mymodule/utils/ipynb.py jinzhongxu/codes/py/pys/mymodule/cv/gif.py jinzhongxu/codes/py/pys/mymodule/cv/image_sam_annotate.py jinzhongxu/codes/py/pys/mymodule/cv/bbox_video.py jinzhongxu/codes/py/pys/mymodule/cv/video.py jinzhongxu/codes/py/pys/mymodule/cv/image.py jinzhongxu/codes/py/pys/mymodule/cv/video_cut.py (base) root@ubuntu-studio:/workspace jinzhongxu/codes/py/audio/server.py:30: format=p.get_format_from_width(wf.getsampwidth()), jinzhongxu/codes/py/audio/record.py:6:chunk = 1024 jinzhongxu/codes/py/audio/record.py:7:sample_format = pyaudio.paInt16 jinzhongxu/codes/py/audio/record.py:9:fs = 44100 jinzhongxu/codes/py/audio/record.py:21: format=sample_format, jinzhongxu/codes/py/audio/record.py:46: wf.setsampwidth(p.get_sample_size(sample_format)) jinzhongxu/codes/py/pys/mymodule/cv/image_sam_annotate.py:12:from segment_anything import SamPredictor, sam_model_registry jinzhongxu/codes/py/pys/mymodule/cv/image_sam_annotate.py:36:def sam_image_annotation( jinzhongxu/codes/py/pys/mymodule/cv/image_sam_annotate.py:43: sam_checkpoint="/disk1/datasets/models/sam/sam_vit_h_4b8939.pth" , jinzhongxu/codes/py/pys/mymodule/cv/image_sam_annotate.py:110: sam = sam_model_registry[model_type](checkpoint=sam_checkpoint) jinzhongxu/codes/py/pys/mymodule/cv/image_sam_annotate.py:111: sam.to(device=device) jinzhongxu/codes/py/pys/mymodule/cv/image_sam_annotate.py:112: predictor = SamPredictor(sam) jinzhongxu/codes/py/pys/mymodule/cv/image_sam_annotate.py:353: default="/disk1/datasets/models/sam/sam_vit_h_4b8939.pth" , jinzhongxu/codes/py/pys/mymodule/cv/image_sam_annotate.py:378: sam_image_annotation( jinzhongxu/codes/py/pys/mymodule/cv/image_sam_annotate.py:385: sam_checkpoint=checkpoint,
在 Linux 系统中我们常使用管道符 |
将上一个命令的标准输出转化为标准输入提供给管道后面的命令,如:
1 echo "hello\nworld" | grep e
结果
命令 grep
能够将管道符的标准输入作为参数进行处理,但并不是所有命令都支持,如 rm
命令:
1 ls /home/jinzhongxu/hello
结果
如果我想删除文件夹 hello 下面的所有文件,我尝试如下命令:
结果
1 2 rm : missing operandTry 'rm --help' for more information.
此时,可以采用 xargs
命令来解决
xargs 命令 xargs(eXtended ARGuments)是给命令传递参数的一个过滤器,它的作用就是将标准输入转为命令行参数。默认情况下 xargs
等同于 xargs echo
。可以为 xargs
指定不同的参数达到不同的功能,如 -n
表示按几行显示,参数后面跟上整数,表示行数。
分隔符 默认 xargs
把空格作为分隔符,但可以使用参数 -d
指定分隔符,如:
1 2 echo 'a b c' | xargs -n1
结果
但是,如果符号之间的分隔符不是空格,而是其他时,就会失效
1 echo 'a.b.c' | xargs -n1
结果
如果指定分隔符 .
,就可以:
1 echo 'a.b.c' | xargs -d. -n1
结果
参数替换 如果管道符后面的命令获取的参数不是放在最后以为,需要使用参数替换,在 xargs
中用参数 -I
来指定替换字符,如:
1 2 把当前路径软链接到 /home/jinzhongxu/hello 下的 new-link echo $(pwd ) | xargs -I {} ln -s {} /home/jinzhongxu/hello/new-link
这里替换符 {}
也可以换成其他的符号,如:
1 2 3 4 echo $(pwd ) | xargs -I currentDir ln -s currentDir /home/jinzhongxu/hello/new-linkecho `pwd ` | xargs -I currentDir ln -s currentDir /home/jinzhongxu/hello/new-link
另一个例子,从文件中读取字符,创建同名的文件夹:
1 cat filename.txt | xargs -I file sh -c 'mkdir file'
执行提示 使用参数 -p
可以提示我们执行的命令,并让我再次判断是否执行:
1 2 3 4 echo '1\n2\n3' | xargs -i touch {}.txtls | xargs -p rm
使用参数 -t
会在终端显示出执行的命令,先打印命令,然后再执行:
1 2 3 4 echo '1\n2\n3' | xargs -i touch {}.txtls | xargs -t rm
文件名中有空格 有些文件名中带有空格,然而 xargs
的默认分隔符就是空格,这导致无法处理带有空格的文件。此时,可以使用参数 -0
指定 null
作为分隔符,同时结合 find
命令的参数 print0
把文件列表以 null
分割:
1 2 3 4 echo '1\n2\n3' | xargs -i touch {}.txtfind . -name "*txt" -print0 | xargs -0 rm
上面命令删除当前路径下的 txt 文件。由于分隔符是null,所以处理包含空格的文件名,也不会报错。有些命令(比如 rm
)一旦参数过多会报错”参数列表过长”,而无法执行,改用 xargs
就没有这个问题,因为它对每个参数执行一次命令。
多行参数 使用参数 -L
可以指定多少行作为一个命令行参数。
1 2 3 xargs find -name "*.docx" "*.textile"
上面命令会报错,可以尝试使用如下命令:
1 2 3 xargs -L 1 find -name "*.docx" "*.textile"
多进程 xargs
默认只用一个进程来执行命令。使用 --max-procs
参数可以指定同时用几个进程来并行执行。 如 --max-procs 3
表示同时使用 3 个进程,--max-procs 0
表示 as many as it can,使用所有 CPU 核心执行。如下命令表示同时关闭尽可能多的 Docker 容器
1 docker ps -q | xargs -n 1 --max-procs 0 docker kill
参考文献
xargs 命令教程
Linux xargs 命令
xargs命令