如何在Linux中使用强大的Xargs命令

本文介绍了Linux下强大的xargs命令,该命令能将标准输入转换为命令执行。文章详细讲解了xargs的基本用法及与find命令配合使用的技巧,包括处理带空格的文件名、确认命令执行前的提示以及使用占位符等。

xargs是Linux中功能最强大的命令之一。在本教程中,我将向您展示如何使用xargs将标准输入转换为命令。

 

什么是xargs命令?

xargs命令从标准输入或另一个命令的输出中读取文本行,并将其转换为命令并执行它们。

您经常会发现xargs命令与find命令一起使用。find命令为您提供文件名列表,而xargs命令使您可以逐个使用这些文件名,就好像它是输入到另一个命令中一样。

由于xargs可以进行重定向,因此我强烈建议您对Linux中的stdin,stdout和管道重定向有所了解

如何使用xargs命令?

 

xargs命令具有以下语法:

xargs [options] [command [initial-arguments]]

但是您可能不会那样使用它。它的强大之处在于将一个命令的输出组合到另一个命令。让我们看一个简单的例子。

在当前目录中,我有一些文本文件,flowers.txt具有所有这些文件的名称:

abhishek@linuxhandbook:~/tutorial$ ls
flowers.txt  lily.txt  one_lotus.txt  rose.txt  three_lotus.txt  two_lotus.txt
abhishek@linuxhandbook:~/tutorial$ cat flowers.txt 
lily.txt
one_lotus.txt
rose.txt
three_lotus.txt
two_lotus.txt

现在,我的目标是要查看flowers.txt中提到的所有文件的文件大小。常识说,我可以结合使用cat命令来显示所有文件名,然后将其通过管道传递给du命令以检查文件大小

但是,如果我直接通过管道传输它,则不会给出flowers.txt文件中提到的每个文件的大小。

abhishek@linuxhandbook:~/tutorial$ du -h
52K	.
abhishek@linuxhandbook:~/tutorial$ cat flowers.txt | du -h
52K	.

为什么?首先,du命令不接受标准输入。其次,cat命令的输出不是单个文件名。这就像一个用换行符分隔的单词。

xargs命令的神奇之处在于它将把这个和文本用空格或换行分隔开,并将它们转换为下一个命令的单独输入。

abhishek@linuxhandbook:~/tutorial$ cat flowers.txt | xargs du -h
4.0K	lily.txt
4.0K	one_lotus.txt
16K	rose.txt
4.0K	three_lotus.txt
16K	two_lotus.txt

可以认为这等同于将这些文件名提供给du命令:

abhishek@linuxhandbook:~/tutorial$ du -h lily.txt one_lotus.txt rose.txt three_lotus.txt two_lotus.txt 
4.0K	lily.txt
4.0K	one_lotus.txt
16K	rose.txt
4.0K	three_lotus.txt
16K	two_lotus.txt

您现在意识到了xargs命令的功能,不是吗?

xargs并查找:彼此制成

您通常会发现它与“查找命令”结合使用。find命令搜索文件和目录,并返回它们的名称。多亏了xargs,您可以将find命令的结果用于特定目的,例如重命名,移动它们,删除它们等等。

假设您要获取所有以.txt结尾并包含单词red的文件。您可以在xargs的帮助下结合使用find和grep命令:

abhishek@linuxhandbook:~/tutorial$ find . -type f -name "*.txt" | xargs grep -l red
./three_lotus.txt
./two_lotus.txt
./rose.txt

处理带空格的文件名

如果您的文件名中带有空格,则将导致问题。假设我将three_lotus.txt重命名为“three lotus.txt”。现在,当通过xargs处理它时,它被视为两个单独的文件,分别为three和lotus.txt。

abhishek@linuxhandbook:~/tutorial$ find . -type f -name "*.txt" | xargs grep -l red
./two_lotus.txt
grep: ./three: No such file or directory
grep: lotus.txt: No such file or directory
./rose.txt

在这种情况下,应使用find命令的-print0选项。它用ASCII空字符而不是换行符分隔行。同样,还应该将xargs与-0一起使用以接受ASCII空值。

abhishek@linuxhandbook:~/tutorial$ find . -type f -print0 -name "*.txt" | xargs -0 grep -l red
./two_lotus.txt
./three lotus.txt
./rose.txt

查看正在执行什么命令

如果要查看在xargs的帮助下正在执行什么命令,可以使用-t选项。它将打印正在执行的实际命令。

abhishek@linuxhandbook:~/tutorial$ find . -type f -name "*.txt" | xargs -t touch
touch ./three_lotus.txt ./two_lotus.txt ./lily.txt ./rose.txt

强制xargs在运行命令之前提示确认

有些情况下需要格外小心,例如删除文件。最好查看将要执行的命令,并可以选择拒绝执行。

您可以使用xargs的-p选项来获取提示。

abhishek@linuxhandbook:~/tutorial$ find . -type f -name "*.txt" | xargs -p rm
rm ./three_lotus.txt ./two_lotus.txt ./lily.txt ./rose.txt ?...n

将占位符与xargs结合使用以获得对它的更多控制

缺省情况下,xargs命令在命令末尾添加标准输入作为参数。当您需要在最后一个参数之前使用它时,会产生一个问题。

例如,如果使用move命令,则首先需要源,然后是目标。如果要将找到的文件移动到目标目录,此命令将不起作用:

abhishek@linuxhandbook:~/tutorial$ find . -type f -name "*.txt" | xargs -p mv new_dir
mv new_dir ./three_lotus.txt ./two_lotus.txt ./lily.txt ./rose.txt ?...y
mv: target './rose.txt' is not a directory

在这里可以在xargs中使用带有选项-I的占位符,如下所示:

abhishek@linuxhandbook:~/tutorial$ find . -type f -name "*.txt" | xargs -p -I {} mv {} new_dir
mv ./three_lotus.txt new_dir ?...n
mv ./two_lotus.txt new_dir ?...n
mv ./lily.txt new_dir ?...n
mv ./rose.txt new_dir ?...n

可以将其视为xargs从find命令获取所有文件名并将其保留在{}中。然后转到mv命令并提供{}的内容。

此处的主要区别在于,不是将所有文件名放在同一命令中,而是一个一个地添加它们。这就是为什么要为每个参数调用mv命令的原因(如上例所示)。

注意:我使用{}作为占位符。您可以将大多数其他字母或字符用作占位符。{}是安全的赌注,易于理解和区分。

使用xargs运行多个命令

您可以使用占位符来使用xargs运行多个命令。

abhishek@linuxhandbook:~/tutorial$ find . -type f -name "*.txt" | xargs -I {} sh -c 'ls -l {}; du -h {}' 
-rw-rw-r-- 1 abhishek abhishek 0 May 28 17:02 ./three_lotus.txt
0	./three_lotus.txt
-rw-rw-r-- 1 abhishek abhishek 0 May 28 17:02 ./two_lotus.txt
0	./two_lotus.txt
-rw-rw-r-- 1 abhishek abhishek 0 May 28 17:02 ./lily.txt
0	./lily.txt
-rw-rw-r-- 1 abhishek abhishek 0 May 28 17:02 ./rose.txt
0	./rose.txt

请记住,占位符不会扩展到下一个管道重定向或其他命令。这就是为什么我在这里使用sh命令的原因。

总是有更多……

我在这里的示例中主要使用find with xargs命令,因为这是您最常看到的内容。但这并不意味着xargs仅限于与find命令一起使用。xargs命令的一个此类实际示例是您要停止所有正在运行的docker容器时

docker ps -q | xargs docker stop

像大多数其他Linux命令一样,xargs也有很多选项。您可以始终参考xargs命令手册页以获取更多信息。

我认为这里列出的xargs命令示例足以让您更好地理解这个很棒的命令。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值