如何在 Linux 上使用 xargs 命令

需要将一些 Linux 命令串在一起,但其中一个不接受管道输入? xargs
可以从一个命令获取输出并将其作为参数发送到另一个命令。
所有标准的 Linux 实用程序都具有三个与之关联的数据流。它们是标准输入流 (stdin)、标准输出流 (stdout) 和标准错误流 (stderr)。
这些流处理文本。我们使用文本将输入 (stdin) 发送到命令,并将响应 (stdout) 作为文本写入终端窗口。错误消息也作为文本 (stderr) 写入终端窗口。
Linux 和类 Unix 操作系统的一个重要特性是能够将一个命令的标准输出输出通过管道传输到第二个命令的标准输入输入。第一个命令不关心它的输出是否进入终端窗口,第二个命令不关心它的输入不是来自键盘。
尽管所有 Linux 命令都具有三个标准流,但并非所有命令都接受另一个命令的标准输出作为其标准输入的输入。这意味着你不能通过管道输入给他们。
xargs
是使用标准数据流构建执行管道的命令。通过使用 xargs
,我们可以使 echo
、rm
和 mkdir
等命令接受标准输入作为参数。
xargs 命令
xargs
将接受管道输入。它还可以接受来自文件的输入。 xargs
使用该输入作为我们告诉它使用的命令的参数。如果我们不告诉 xargs
使用特定命令,它将默认使用 echo
。
我们可以用它来演示 xargs
如何始终生成单行输出,即使是多行输入也是如此。
如果我们将 -1
(每行列出一个文件)选项与 ls
一起使用,我们将得到一列文件名。
ls -1 ./*.sh

这会列出当前目录中的 shell 脚本文件。

我们得到了预期的单列。如果我们通过 xargs
对其进行管道传输,我们会得到什么?
ls -1 ./*.sh | xargs

输出作为一长串文本写入终端窗口。

正是这种能力让我们将 xargs
参数提供给其他命令。
将 xargs 与 wc 一起使用
我们可以使用 xargs
轻松地让 wc
计算多个文件中的单词、字符和行数。
ls *.page | xargs wc

这是发生了什么:
ls
列出 *.page 文件并将列表传递给xargs
。xargs
将文件名传递给wc
。wc
将文件名视为已将其作为命令行参数接收。

每个文件的统计数据与总计一起显示。
使用 xargs 进行确认
我们可以使用 -p
(交互式)选项让 xargs
提示我们确认我们很乐意继续进行。
如果我们通过 xargs
将一串文件名传递给 touch
,touch
将为我们创建文件。
echo 'one two three' | xargs -p touch

显示将要执行的命令,xargs
等待我们通过键入“y”或“Y”或“n”或“N”并按 Enter 进行响应。
如果你只是按回车,它被视为“n”。该命令仅在您键入“y”或“Y”时执行。

我们按下“y”并按下 Enter。我们可以使用 ls
来检查文件是否已经创建。
ls one two three

将 xargs 与多个命令一起使用
我们可以使用 xargs
的多个命令,方法是使用 -I
(初始参数)选项。
该选项定义了一个“替换字符串”。无论替换字符串的标记出现在命令行中的什么位置,都会插入提供给 xargs
的值。
让我们使用 tree
命令查看当前目录的子目录。 -d
(目录)选项导致 tree
忽略文件并只报告目录。
tree -d

有一个名为“images”的子目录。
在名为“directories.txt”的文件中,我们有一些我们希望创建的目录的名称。我们可以使用 cat
查看它的内容。
cat directories.txt

我们将使用它作为 xargs
的输入数据。我们要执行的命令是:
cat directories.txt | xargs -I % sh -c 'echo %; mkdir %'
这分解如下:
- cat directories.txt |:这会将 directrories.txt 文件的内容(所有新目录名称)推送到
xargs
。 - xargs -I %:这定义了一个带有标记“%”的“替换字符串”。
- sh -c:这会启动一个新的子 shell。
-c
(命令)告诉 shell 从命令行读取命令。 - 'echo %; mkdir %':每个“%”标记都将替换为
xargs
传递的目录名称。echo
命令将打印目录名称;mkdir
命令将创建目录。

目录一一列出。

我们可以再次使用 tree
来验证目录是否已经创建。
tree -d

将文件复制到多个位置
我们可以使用 xargs
允许我们使用单个命令将文件复制到多个位置。
我们将把两个目录的名称作为输入参数传送到 xargs
中。我们将告诉 xargs
一次只将这些参数之一传递给它正在使用的命令。
在这种情况下,命令是 cp
。所以效果是调用 cp
两次,每次都将两个目录之一作为命令行参数。允许这种情况发生的 xargs
参数是 -n
(最大数量)选项。我们将把它设置为一个。
我们还在 cp
中使用了 -v
(详细)选项,以便它报告正在发生的事情。
echo ~/Backups/ ~/Documents/page-files/ | xargs -n 1 cp -v ./*.page

文件被复制到两个目录,一次一个目录。 cp
报告每个文件复制操作,以便我们可以看到它们的发生。

删除嵌套目录中的文件
如果文件名中有空格和奇怪的字符(例如换行符),xargs
将无法正确解释它们。我们可以通过使用 -0(空终止符)选项来解决这个问题。这告诉 xargs
使用空字符作为文件名的最终分隔符。
我们将在这个例子中使用 find
。 find
有自己的选项来处理文件名中的空格和奇怪字符。它是 -print0
(全名,空字符)选项。
find . -name "*.png" -type f -print0 | xargs -0 rm -v -rf "{}"
这分解如下:
- 找到 . -name “*.png”:
find
将从当前目录“.”开始搜索对于名称与“*.png”匹配的文件对象 (type -f
)。 - -print0:名称将以空字符结束,并考虑空格和奇怪字符。
- xargs -0:xargs 还将考虑文件名以 null 结尾,空格和奇怪的字符不会造成问题。
- rm -v -rf “{}”:rm 将变得冗长并报告正在发生的事情 (
-v
)。它将递归 (-r) 并查看嵌套的子目录,并且将在不提示的情况下删除文件 (-f
)。 “{}”由每个文件名替换。

搜索所有子目录,并删除与搜索模式匹配的文件。

删除嵌套目录
假设我们要删除一组嵌套的子目录。 tree
会让我们看到它们。
tree -d

find . -name "level_one" -type d printo | xargs -o rm -v -rf "{}"
此命令将使用 find 在当前目录中递归搜索。搜索目标是名为“level_one”的目录。目录名称通过 xargs
传递给 rm
。

此命令与前一个命令之间唯一的显着变化是,搜索词是最顶层目录的名称,-type d
告诉 find
查找目录,而不是文件。

每个目录的名称在删除时打印出来。我们可以检查 tree
:
tree -d

所有嵌套的子目录都被删除。
删除所有文件,一种文件类型除外
我们可以使用find
、xargs
和rm
来删除除我们要保留的一种类型之外的所有文件。这有点违反直觉,但我们提供了我们希望保留的文件类型的名称,而不是我们要删除的文件类型的名称。
-not
选项告诉 find
返回不匹配搜索模式的文件名。我们再次将 -I
(初始参数)选项与 xargs
一起使用。这次我们定义的替换字符串标记是“{}”。这与我们之前生成的替换字符串标记的行为完全相同,后者恰好是一个“%”。
find . -type f -not - name "*.sh" -print0 | xargs -0 -I {} rm -v {}

我们可以使用 ls
检查。目录中唯一剩下的文件是与“*.sh”搜索模式匹配的文件。
ls -l

使用 Xargs 创建存档文件
我们可以使用 find
来搜索文件并将它们通过 xargs
传递给 tar
,以创建存档文件。
我们将在当前目录中搜索。搜索模式是“*.page”,所以我们要寻找“.page”文件。
find ./ - name "*.page" -type f -print0 | xargs -0 -tar -cvzf page_files.tar.gz

在创建存档文件时,文件按预期列出。

数据中介
有时,当你把东西堆在一起时,你需要一个小脚手架。 xargs
弥合了可以输出信息的命令和无法接收信息的命令之间的差距。
xargs
和 find
都有大量的选项。我们鼓励您查看他们的手册页以了解更多信息。
Linux Commands | ||
Files | tar · pv · cat · tac · chmod · grep · diff · sed · ar · man · pushd · popd · fsck · testdisk · seq · fd · pandoc · cd · $PATH · awk · join · jq · fold · uniq · journalctl · tail · stat · ls · fstab · echo · less · chgrp · chown · rev · look · strings · type · rename · zip · unzip · mount · umount · install · fdisk · mkfs · rm · rmdir · rsync · df · gpg · vi · nano · mkdir · du · ln · patch · convert · rclone · shred · srm · scp · gzip · chattr · cut · find · umask · wc | |
Processes | alias · screen · top · nice · renice · progress · strace · systemd · tmux · chsh · history · at · batch · free · which · dmesg · chfn · usermod · ps · chroot · xargs · tty · pinky · lsof · vmstat · timeout · wall · yes · kill · sleep · sudo · su · time · groupadd · usermod · groups · lshw · shutdown · reboot · halt · poweroff · passwd · lscpu · crontab · date · bg · fg · pidof · nohup · pmap | |
Networking | netstat · ping · traceroute · ip · ss · whois · fail2ban · bmon · dig · finger · nmap · ftp · curl · wget · who · whoami · w · iptables · ssh-keygen · ufw · arping · firewalld |
RELATED: Best Linux Laptops for Developers and Enthusiasts