Linux——关于xargs命令的使用

2024-07-01  本文已影响0人  moutory

前言

xargs命令在我们需要批量执行命令、复杂命令的参数传递时特别有用,下文就来介绍一下这个命令的用法吧

一、前置知识点

xargs命令和标准输入有着一定的关系,在介绍这个命令之前我们不妨先了解标准输入、标准输出和错误输出分别是什么?

二、 xargs命令存在的作用

假设现在存在文件test.txt,文件内容如下:

aa
bb
cc

我们执行cat test.txt | grep aa,可以发现命令可以正常执行成功,这说明grep是支持标准输入作为入参的

image.png

如果我们执行cat test.txt | echo命令会发现,test.txt的内容并没有被打印出来,这是因为在Linux系统中,部分命令时不接受标准输入作为入参的

image.png

对于这类不支持标准输入作为入参的命令,linux提供了xargs命令来帮助我们进行桥接,或者说将标准输入转为命令行参数

三、使用键盘输入作为标准输入使用xargs命令

xargs命令支持我们单独执行,默认情况下xargs相当于是xargs echo,当我们输出xargs时,控制台将会开始监听你的键盘输入,按ctrl + d打印最终的结果。

image.png

我们还可以结合其他命令来使用

$ xargs find -name
"*.txt"
./foo.txt
./hello.txt

上面的例子输入xargs find -name以后,命令行会等待用户输入所要搜索的文件。用户输入"*.txt",表示搜索当前目录下的所有 TXT 文件,然后按下Ctrl+d,表示输入结束。这时就相当执行find -name *.txt

四、不同参数的使用

(一)使用-d参数修改分隔符

默认情况下,xargs命令将换行符和空格作为分隔符,把标准输入分解成一个个命令行参数。
例如下图中的案例

使用换行符作为分隔符
使用换行符作为分隔符
使用空格作为分隔符
使用空格作为分隔符
需要注意的是,如果同时存在换行符或者空格,那么xargs命令会基于这两种方式一起切割

如果标准输入不是以“空格”或者“换行符”进行分隔的话,我们可以通过-d参数手动指定分隔符,具体可以看下面的案例

使用&作为标准换行符
echo -n "aa&bb&cc" | xargs -d "&" mkdir
(二)使用-p 参数,-t 参数打印最终执行的命令

由于xargs命令做了一层标准输入转入参的功能,所以有时候我们不能很方便的知道最终执行的命令是什么,这其实也是有一点点小小的风险,不过xargs其实也是支持我们对最终的命令执行打印操作的。

(三)使用-I参数,定义参数名用于多次使用

从上文的使用中我们不难发现,对于一个标准输入,xargs命令只能把它转换为入参用1次,但有时候我们需要重复用到这个入参,这个时候我们就可以使用-I参数来完成我们的操作。
譬如当前目录中存在aa1aa2aa3三个文件,我们希望把这些aa开头的文件统一加上.txt后缀,我们可以使用ls | grep aa | xargs -I fileName -t mv fileName fileName.txt命令来完成操作。(这里的-t参数只是为了打印,可以不加)
我们简单分析一下这条命令吧,ls命令打印当前目录下的文件,grep aa过滤出符合重命名条件的文件,xargs -I fileName命令将得到的入参设了一个临时的变量名fileName,mv fileName fileName.txt这里就是使用前面定义的fileName变量名

image.png
关于变量名的定义,比较通用的做法是把入参定义为{},原因是使用 {} 作为占位符简洁明了,它直观地表示了这是一个将要被替换的位置。也就是说上面那条命令可以改写为ls | grep aa | xargs -I {} -t mv {} {}.txt

(四)使用-L参数定义多少行作为一个命令行参数

假设我们现在有一个dirName文件,文件内容是

aa1
bb1
cc1

我们希望根据这个文件里面的内容来作为目录名进行文件创建,那么我们执行cat dirName | xargs -p mkdir命令,可以看到其实最终执行的命令是只有一条,就是mkdir aa1 bb1 cc1。执行肯定是没有问题的,虽然xargs命令一股脑把所有参数都传了过去,但因为mkdir命令天然支持同时传入多个目录名来进行目录创建,所以命令在执行上也没有问题

image.png
但实际上,有些命令是不支持同时传入多个参数的,或者是一些命令支持批量操作的入参数量有限制,比如说find命令就不支持同时传入多个参数。这个时候就会要求我们把三个参数分成三次传入,也就是说命令会执行3次
image.png
这时我们就可以传入-L 1来让每行作为1个命令行参数(也就是说这个命令每次执行至多接受1行的参数
image.png

(五)使用-n参数定义多少项作为一个命令行参数

这个命令是基于有时候输入流不一定是每行只有一个参数的前提下出现的,我们在前文中提到了默认情况下xargs命令会基于空格和换行符进行参数的分割,但是有时候由于一行之中可能又会切割出多个参数出来,所以直接用-L可能不太准确。可以直接选择-n参数来确定每次以多少个参数作为一个命令行参数。
比如说现在切分完成后一共得到了40个参数,我希望每次执行命令的时候依次传入2个参数,就可以使用-n 2来实现。具体看案例:
我们希望把xargs切分后的参数,每次只传1个参数到命令行中,来实现批量查询,就可以用cat dirName | xargs -n 1 -t find ./ -name-t参数可以省略)

使用-n参数

(六)使用--max-procs参数进行多进程执行

xargs默认只用一个进程执行命令。如果命令要执行多次,必须等上一次执行完,才能执行下一次。
--max-procs参数指定同时用多少个进程并行执行命令。--max-procs 2表示同时最多使用两个进程,--max-procs 0表示不限制进程数。
比如删除当前目录下的所有文件:ls | xargs -n 1 -t --max-procs 2 rm -rf

小结

总的来说,xargs命令可以帮助我们实现一些很酷很便捷的脚本操作,掌握这个命令会让工作简单不少。

一些常用的命令
删除当前目录内名称不包含fileName的所有文件
find -type f . ! -name fileName* | xargs -n 1 -t rm -rf

参考文章

xargs 命令教程 https://ruanyifeng.com/blog/2019/08/xargs-tutorial.html

上一篇 下一篇

猜你喜欢

热点阅读