Bash脚本中的xargs

  |  

摘要: 本文简单了解一下在 shell 脚本中 args 命令的作用和用法

【对数据分析、人工智能、金融科技、风控服务感兴趣的同学,欢迎关注我哈,阅读更多原创文章】
我的网站:潮汐朝夕的生活实验室
我的公众号:潮汐朝夕
我的知乎:潮汐朝夕
我的github:FennelDumplings
我的leetcode:FennelDumplings


xargs

xargs 的全称是 eXtended ARGuments,是给命令传递参数的过滤器

  • xargs 可以将管道或标准输入(stdin)数据转换成命令行参数,也能够从文件的输出中读取数据。
  • xargs 可以将单行或多行文本输入转换为其他格式,例如多行变单行,单行变多行。
  • xargs 默认的命令是 echo,通过管道传递给 xargs 的输入包含换行和空白,经过 xargs 的处理,换行和空白将被空格取代。

很多命令不支持管道来传递参数,因此 xargs 很有用。

参数

xargs 的常用参数如下:

  • -a: file 从文件中读入作为 stdin
  • -e: flag,注意有的时候可能会是-E,flag 必须是一个以空格分隔的标志,当 xargs 分析到含有 flag 这个标志的时候就停止。
  • -p: 当每次执行一个 argument 的时候询问一次用户。
  • -n: num 后面加次数,表示命令在执行的时候一次用的 argument 的个数,默认是用所有的。
  • -t: 表示先打印命令,然后再执行。
  • -i/-I: 将 xargs 的每项名称,一般是一行一行赋值给 {},可以用 {} 代替。
  • -r: no-run-if-empty 当 xargs 的输入为空的时候则停止 xargs,不用再去执行了。
  • -s: num 命令行的最大字符数,指的是 xargs 后面那个命令的最大命令行字符数。
  • -L/-l: num 从标准输入一次读取 num 行送给 command 命令。
  • -d: delim 分隔符,默认的 xargs 分隔符是回车,argument 的分隔符是空格,这里修改的是 xargs 的分隔符。
  • -x: exit 的意思,主要是配合 -s 使用。
  • -P: 修改最大的进程数,默认是 1,为 0 时候为 as many as it can,这个例子我没有想到,应该平时都用不到的吧。

例子

假设有一个文件 test.txt

1
2
3
4
5
a b c d e f g
h i j k l m n
o p q
r s t
u v w x y z

多行转一行

1
cat test.txt | xargs

转多行

1
cat test.txt | xargs -n3

自定义分隔符

默认分隔符是回车。

1
echo "nameXnameXnameXname" | xargs -dX

将格式化后端额命令传递给命令

使用 -I 指定一个替换字符串 {},这个字符串在 xargs 扩展时会被替换掉,当 -I 与 xargs 结合使用,每一个参数命令都会被执行一次。

假设有 arg.txt 文件:

1
2
3
aaa
bbb
ccc

也有一个 shell 脚本,功能是打印所有参数:

1
$*

命令如下:

1
cat arg.txt | xargs -I {} ./sk.sh -p {} -l

结果如下:

1
2
3
-p aaa -l
-p bbb -l
-p ccc -l

复制所有 jpg 文件到 /data/images 目录下

1
ls *.jpg | xargs -n1 -I {} cp {} /data/images

xargs 结合 find 使用

删除大量文件

用 rm 删除太多的文件时候,可能得到一个错误信息:/bin/rm Argument list too long. 用 xargs 去避免这个问题。

1
find . -type f -name "*.log" -print0 | xargs -0 rm -f

其中 xargs -0 将 \0 作为定界符。

统计所有 cpp 文件的行数

1
find . -type f -name "*.cpp" -print0 | xargs -0 wc -l

查找所有 jpg 文件,压缩它们

1
find . -type f -name "*.jpg" -print | xargs tar -czvf images.tar.gz

下载大量 URL

1
cat url-list.txt | xargs wget -c

Share