xargs命令

extended arguments
xargs命令的作用,是将标准输入转为命令行参数。
结合管道,它能把一个命令的输出,变为另外一个命令的参数。

一、参数与标准输入

命令都带参数,有些命令可以接受"标准输入"(stdin)作为参数。

参数:ls test.txt
标准输入:cat /etc/passwd | grep root

怎么分辨一个命令可不可以接收标准输入?
很简单,当你敲完命令回车后,终端会等待接收你的输入,例如当你在终端输入cat后,终端会等待你输入字符,当你输入一些字符后,然后按Ctrl-d发送终止符号。这时cat命令接收标准输入完毕,执行命令,也就是将刚才键入的内容输出的标准输出上(屏幕)。

之所以有xargs这个命令,是因为大多数命令都不接受标准输入作为参数,这导致无法用管道命令传递参数。

find /sbin -perm +700 | ls -l #这个命令是错误的
find /sbin -perm +700 | xargs ls -l #这样才是正确的

xargs 一般是和管道一起使用。

二、命令格式

command1 | xargs [options] command2

三、选项

-a file 从文件中读入作为 stdin
-e flag ,注意有的时候可能会是-E,flag必须是一个以空格分隔的标志,当xargs分析到含有flag这个标志的时候就停止。
-p 当每次执行一个argument的时候询问一次用户。
-n num 后面加次数,表示命令在执行的时候一次用的argument的个数,默认是用所有的。
-t 表示先打印命令,然后再执行。
-i 或者是-I,将参数赋值给 {},可以用 {} 代替。
-r no-run-if-empty 当xargs的输入为空的时候则停止xargs,不用再去执行了。
-s num 命令行的最大字符数,指的是 xargs 后面那个命令的最大命令行字符数。
-L num 从标准输入一次读取 num 行送给 command 命令。
-l 同 -L。
-d delim 分隔符,默认的xargs分隔符是空白
-x exit的意思,主要是配合-s使用。
-P, --max-procs=MAX-PROCS    同时运行至多<MAX-PROCS>个进程

四、用法实例

1.单独使用


大多数时候,xargs命令都是跟管道一起使用的。但是,它也可以单独使用。

xargs后面的命令默认是echo。
xargs 等同于 xargs echo

xargs hello(Ctrl + d)
hello

再看一个例子

xargs find -name "*.txt"(Ctrl + d)
./foo.txt ./hello.txt

就相当执行

find -name “*.txt”

2.-0与find


由于xargs默认以空白(包括空格、Tab、换行)作为分隔符,所以不太适合处理文件名,因为文件名可能包含空格。
find命令有一个特别的选项-print0,表示find输出的每条结果后面加上 ‘\0’ 也就是null,而不是换行。
xargs命令的-0选项表示用null当作分隔符。

find /path -type f -print0 | xargs -0 rm
上面命令删除/path路径下的所有文件。由于分隔符是null,所以处理包含空格的文件名,也不会报错。

xargs 的-0选项不仅可以将分隔符从默认的空格变成 NULL,还会将单引号、双引号、反斜线等统统默认为是普通字符。所以说,-0选项特别适合处理命令参数中含有引号、空格、反斜线的情况。

还有一个原因,使得xargs特别适合find命令。有些命令(比如rm)一旦参数过多会报错"参数列表过长",而无法执行,改用xargs就没有这个问题,因为它对每个参数执行一次命令。

find . -name "*.txt" -print0 | xargs -0 grep -l "abc"
上面命令找出所有 TXT 文件以后,对每个文件搜索一次,看是否包含字符串abc。
sudo find / -name '*.*' -type f -print0 | xargs -0 sudo grep -l 'alias ll='
查找包含特定内容的文件

3.-i


-i arg的意思是用arg代替每个参数

ls *.jpg | xargs -n1 -i arg cp arg /data/images
复制所有图片文件到 /data/images 目录下

4.-t


先打印命令再执行命令

ls | xargs -t -i arg echo arg
会打印echo命令,然后再执行的 echo 命令

5.-d


默认情况下xargs以空白(包括空格、Tab、回车换行等)分割输入流,我们可以使用 -d 命令指定分隔符,例如:

echo '11@22@33' | xargs echo
输出:
11@22@33

默认情况下以空白分割,那么11@22@33这个字符串中没有空白,所以实际上等价于 echo 11@22@33 其中字符串 ‘11@22@33’ 被当作echo命令的一个命令行参数

echo '11@22@33' | xargs -d '@' echo
输出:
11 22 33

指定以@符号分割参数,所以等价于 echo 11 22 33 相当于给echo传递了3个参数,分别是11、22、33

-0 和 -d ‘\0’ 是等价的。

6.-p


执行命令时提示,我们可以输入 y 或者 n 来选择是否要执行当前命令:

find . -type f |xargs -p rm -f
rm -f ./china.txt ./usa.txt ./japan.txt ?...n
上面的命令中,我们输入了“n”,也就是不希望删除这三个文件。

7.-n


-n 3 表示一次传递给xargs后面的命令是3个参数

echo '11@22@33@44@55@66@77@88@99@00' | xargs -d '@' -n 3 echo
输出结果:
11 22 33
44 55 66
77 88 99
00

等价于:

echo 11 22 33
echo 44 55 66
echo 77 88 99
echo 00

实际上运行了4次,每次传递3个参数,最后还剩一个,就直接传递一个参数。

8.-E 选项


-E arg 表示当传递的参数是arg时命令结束。

echo '11 22 33' | xargs -E '33' echo
输出:
11 22

9.-P,–max-procs


xargs默认只用一个进程执行命令。如果命令要执行多次,必须等上一次执行完,才能执行下一次。
–max-procs选项指定同时用多少个进程并行执行命令。
–max-procs 2表示同时最多使用两个进程,
–max-procs 0表示不限制进程数。

docker ps -q | xargs -n 1 --max-procs 0 docker kill
上面命令表示,同时关闭尽可能多的 Docker 容器,这样运行速度会快很多。

10.配合grep


Altitest.py python.py runora.py test.py TransferFile.p
存在以上文件

find . -name '*.py' |grep test
./Altitest.py
./test.py
将前面命令的标准输出作为标准输入传给了grep test,搜索的是文件名列表
find . -name '*.py' -print0 |xargs -0 grep test
./runora.py:testConn = cx_Oracle.connect('user/passwd@tns')
./runora.py:testCursor = testConn.cursor()
./runora.py:testCursor.execute("select * from table")
./runora.py:rows = testCursor.fetchall()
./runora.py:testCursor.close()
./runora.py:testConn.close()
将前面命令的标准输出作为参数传给了grep test,搜索的是文件内容

### Xargs命令与Exec的区别 Xargs和exec都是Linux系统中用于将参数传递给其他命令的方式,但在具体实现上有所不同。 #### 工作原理差异 Xargs从标准输入读取数据并将其作为参数传递给指定的命令。这种方式允许更灵活地处理大量参数,因为xargs可以自动调整每次调用命令时所使用的参数数量[^2]。相比之下,`find ... -exec`直接在找到文件后立即执行指定的操作,对于每一个匹配项都会启动一个新的进程来运行命令[^1]。 #### 参数传递方式的不同 当使用xargs时,可以通过设置最大参数长度或限制每批次发送到目标命令中的项目数,从而优化性能表现。而-exec则是针对每个单独的结果去执行相应的操作,这意味着如果查找出来的文件非常多,则可能会创建大量的子进程[^3]。 #### 性能对比 由于xargs能够批量处理多个参数,在某些情况下效率更高;特别是当需要对很多小文件进行相同操作的时候,利用xargs通常可以获得更好的性能提升。然而,在简单场景下两者之间的速度差距可能并不明显。 #### Shell脚本示例 下面给出一段简单的shell脚本来展示如何分别使用这两种方法: ```bash #!/bin/bash # 使用 find 和 xargs 的组合 echo "Using find and xargs:" find /path/to/search -name "*.log" | xargs rm -f # 或者也可以这样写以提高兼容性和安全性 find /path/to/search -name "*.log" -print0 | xargs -0 rm -f # 使用 find 和 exec echo "Using find with -exec:" find /path/to/search -name "*.log" -exec rm -f {} \; ``` 这段代码展示了两种不同的删除特定目录下的日志文件的方法。前者先找出所有的`.log`文件并将它们一次性交给rm命令移除;后者则是每当发现符合条件的日志文件就立刻调用一次rm命令对其进行清理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值