xargs命令
xargs 命令是一个非常好用的 Linux 命令,它可以将管道或标准输入转换成命令行参数,并用这些参数来执行指定
的命令。默认情况下, xargs 命令会将输入按照空格、制表符、换行符等符号进行分隔,并将它们作为一组参数
传递给指定的命令。如果没有输入,则 xargs 命令会读取用户的键盘输入,并将其用作参数。
1、命令格式
shell
somecommand |xargs -item command
-
-a file 从文件中读入作为 stdin
-
-e flag ,注意有的时候可能会是-E,flag必须是一个以空格分隔的标志,当xargs分析到含有flag这个标志的时
候就停止。
-
-p 当每次执行一个argument的时候询问一次用户。
-
-n num 后面加次数,表示命令在执行的时候一次用的argument的个数,默认是用所有的。
-
-t 表示先打印命令,然后再执行。
-
-i 或者是-I,这得看linux支持了,将xargs的每项名称,一般是一行一行赋值给 {},可以用 {} 代替。
-
-r no-run-if-empty 当xargs的输入为空的时候则停止xargs,不用再去执行了。
-
-s num 命令行的最大字符数,指的是 xargs 后面那个命令的最大命令行字符数。
-
-L num 从标准输入一次读取 num 行送给 command 命令。
-
-l 同 -L。
-
-d delim 分隔符,默认的xargs分隔符是回车,argument的分隔符是空格,这里修改的是xargs的分隔符。
-
-x exit的意思,主要是配合-s使用。。
-
-P 修改最大的进程数,默认是1,为0时候为as many as it can ,这个例子我没有想到,应该平时都用不到的
吧。
2、实例1
例如,要将当前目录下所有 .txt
文件删除,可以使用下列命令:
shell
$ echo a > a.txt
$ echo b >b.txt
$ ls
a.txt b.txt
$ ls *.txt | xargs rm
$ ls
此命令将列出当前目录中的所有 .txt
文件,并将它们作为参数传递给 rm 命令,删除这些文件。
3、实例2
但是,在某些情况下,xargs 命令的默认行为可能不符合我们的需求。在这种情况下,可以使用 -I 选项来自定义参
数的分隔符。
-I 选项的语法是 -I <替代字符串>,它允许您在命令行中使用替代字符串来代替 xargs 接收到的参数。特别地,{}
符号通常用作替代字符串。当 xargs 命令遇到 {} 符号时,它会将其替换为输入中的值,然后执行指定的命令。
例如,要在当前目录下的所有 .txt
文件中搜索 hello
并显示匹配行的上下文,请使用以下命令:
shell
$ echo hello > a.txt
$ echo world >b.txt
$ ls
a.txt b.txt
$ ls *.txt | xargs -I{} grep -C2 "hello" {}
hello
此命令将把 ls 命令的输出作为 xargs 命令的输入,并将每个文件名替换为 {}。xargs 命令会将每个文件名作为参
数传递给 grep 命令并执行它。
另一个示例是,要从用户列表中删除所有以 user 开头的用户帐户,请使用以下命令:
shell
grep "^user" /etc/passwd | cut -d ":" -f 1 | xargs -I{} sudo userdel {}
此命令会列出 /etc/passwd
文件中以 user 开头的用户帐户,然后根据 : 分隔符对其进行分割并只取第一列,最
后使用 {} 符号将用户名作为参数传递给 xargs 命令,然后执行 sudo userdel
删除用户帐户。
因此, -I{} 选项可以让我们在 xargs 命令中自定义替代字符串,使得我们能够精确地控制被传递的参数和参数之间
的分隔符,这有助于构建更加复杂和准确的命令。
4、实例3
很多命令不支持|管道来传递参数,这时就可以使用 xargs 命令:
shell
$ echo hello > a.txt
$ echo world >b.txt
$ ls
a.txt b.txt
# 错误使用
$ find ./ -name a.txt |ls
a.txt b.txt
# 正确使用
$ find ./ -name a.txt |xargs ls
./a.txt
5、实例4
xargs 用作替换工具,读取输入数据重新格式化后输出。
定义一个测试文件,内有多行文本数据:
shell
$ cat >>test.txt << EOF
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
EOF
# 多行输入单行输出
$ cat test.txt | xargs
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
# -n 选项多行输出
$ cat test.txt | xargs -n3
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
# -d 选项可以自定义一个定界符
$ echo "nameXnameXnameXname" | xargs -dX
name name name name
# 结合 -n 选项使用
$ echo "nameXnameXnameXname" | xargs -dX -n2
name name
name name
6、实例5
读取 stdin,将格式化后的参数传递给命令
假设一个命令为 sk.sh
和一个保存参数的文件 arg.txt
:
shell
# sk.sh文件内容
#!/bin/bash
echo $*
shell
# arg.txt文件内容
cat >> arg.txt << EOF
aaa
bbb
ccc
EOF
xargs 的一个选项 -I,使用 -I 指定一个替换字符串 {},这个字符串在 xargs 扩展时会被替换掉,当 -I 与 xargs 结合
使用,每一个参数命令都会被执行一次:
shell
$ cat arg.txt | xargs -I {} ./sk.sh -p {} -l
-p aaa -l
-p bbb -l
-p ccc -l
7、实例6
复制所有图片文件到 /data/images 目录下:
shell
$ ls *.jpg | xargs -n1 -I {} cp {} /data/images
xargs 结合 find 使用,用 rm 删除太多的文件时候,可能得到一个错误信息:
/bin/rm Argument list too long.
用 xargs 去避免这个问题:
shell
# xargs -0 将 \0 作为定界符
# find命令默认接的命令是-print,它默认以\n将找到的文件分隔,可以使用-print0来使用\0分隔,这样就不会分行了
$ find . -type f -name "*.log" -print0 | xargs -0 rm -f
统计一个源代码目录中所有 php 文件的行数:
shell
$ find . -type f -name "*.php" -print0 | xargs -0 wc -l
查找所有的 jpg 文件,并且压缩它们:
shell
$ find . -type f -name "*.jpg" -print | xargs tar -czvf images.tar.gz
xargs 其他应用,假如你有一个文件包含了很多你希望下载的 URL,你能够使用 xargs下载所有链接:
shell
$ cat url-list.txt | xargs wget -c