总结
xargs
是一个能将命令的输出转换为另一个命令的参数的工具,它能让一些命令例如:echo
,rm
,和mkdir
等接受标准输入作为参数来执行操作。xargs
可以和wc
等命令一起使用,并且能够轻松地去统计多个文件的单词数,字符数和行数。xargs
可用于将文件复制到多个位置和删除嵌套目录中的文件,以及使用find
命令创建归档文件。
为什么使用xargs命令?
xargs
命令常用于在标准的数据流结构上建立在一个可执行管道。换句话说,你可以使用xargs
命令的输出作为参数发送到另一个命令。- 所有标准的Liunx实用程序有三个与之相关联的数据流,它们分别为标准输入流(stdin),标准输出流(stdout)和标准错误流(stderr),通过使用
xargs
命令我们可以让一些命令,例如echo
,rm
,和mkdir
作为参数接受标准输入。 - 这些流在文本中运行,我们使用文本向命令发送输入(stdin),并且响应(stdout)作为文本写入终端窗口中。错误的信息也会以文本的形式(stderr)写入到终端窗口中。
- Linux和Unix操作系统都有一个重要的特性:能够将一个命令的标准输出(stdout)通过管道符传递给另一个命令的标准输入(stdin)中。第一个命令不用在意它的输出没有发送到终端窗口,第二个命令不必在意它的输入不是来自键盘。
- 尽管所有的Linux命令有三个标准流,但不是所有的命令都接受另一个命令的标准输出作为其标准输入。这也意味着你不能通过管道符向它们输出。
- 这就是
xargs
命令的所用之处,我们介绍了一些可实用的xargs
命令例子 - 你可以随意跳过任何一个点。这些例子不一定要建立在彼此的基础上。
xargs 命令
-
xargs
命令可以接受管道符输入。它也可以从文件中接受输入。xargs
使用这个输入作为我们告诉它如何使用这个命令的参数 。如果我们没有告诉xargs
如何使用具体的命令,那么它将会默认去使用echo
命令。 -
我们可以使用
xargs
如何生产单行输出,甚至从多行输入去演示。 -
如果我们在
ls
中使用-l
(每行列出一个文件)的选项,我们将得到一列文件名ls -l ./*.sh
-
这将会列出当前目录中的
shell
脚本文件 -
我们可以得到一个预期的单列。如果我们通过
xargs
管道符去传递那我们会得到什么?ls -l ./*.sh | xargs
-
这个输出结果会作为一个长串的文本写入终端窗口中
-
正是这种功能使
xargs
将参数提供给其它的命令
将xargs与wc一起结合使用
-
我们可以使用
xargs
命令去轻松地实现让wc
命令统计多个文件中的单词数,字符数和行数。ls *.page | xargs wc
-
具体过程如下:
ls
命令首先会列出所有.page
后缀的文件并传递给xargs
xargs
将这些文件名传递给wc
命令wc
会将文件名当作接收到的命令行参数来处理
-
会显示每个文件的统计信息,并附带一个总计的结果
执行前需要确认的xargs用法
-
我们可以使用
-p
(交互式)选项让xargs
在执行前请求确认是否继续操作 -
如果我们通过
xrags
将文件名列表传递给touch
命令,touch
会为我们创建这些文件echo 'one two three' | xargs -p touch
-
将要执行的命令显示出来,
xargs
会等待我们输入'y'
或'Y'
(确认执行),或者'n'
或'N'
(取消执行),然后按Enter
键响应 -
如果你只按下
Enter
键,系统会默认视为'n'
(取消执行),只有输入'y'
或'Y'
时,命令才会被实际执行 -
我们输入了
'y'
并按下Enter
,此时可以使用ls
命令来进行查看,确认文件已经被创建成功ls one two three
使用xargs命令执行多命令操作
-
通过使用
-l
(初始化参数)这个选项,我们可以对xargs
使用多个命令 -
该选项用于定义一个"替换字符串",当命令行中出现该代替字符串时,
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 |
:将*directories.txt*
文件的内容**(所有待创建的目录名称)通过管道符**输送给xargs
xargs -I %
:定义"%"
作为一个替换标记符,后续命令中出现的%
都会被实际参数替换sh -c
:这会启动一个新的子shell
环境,-c
参数表示从命令行读取要执行的指令- ‘
echo %; mkdir %
’:这会将执行两个命令,echo %
先打印当前正在处理的目录名,mkdir %
随后创建对应的目录,所有%
符号都会被xargs
逐行替换为输入的目录名
-
系统会逐个列出并处理目录项
-
我们可以再次使用
tree
命令来验证目录是否已经被成功创建tree -d
将文件复制到多个位置
-
我们可以使用
xargs
通过单个命令将文件复制到多个位置 -
我们将通过管道符把两个目录名作为输入参数传递给
xargs
,并且我们可以通过参数设置告诉xargs
每次只能传递其中的一个参数给目标命令 -
在本次例子中,操作命令为
cp
。所以当实际执行时,xargs
会分别调用两次cp
命令,并且每次只能传递一个命令行参数。实现该功能在于xargs
的-n
(最大参数)选项,此处我们将其设置为1
-
我们也为
cp
命令添加了-v
(verbose)选项,使其实时显示每个文件的操作详情echo ~/Backups/ ~/Documents/page-files/ | xargs -n 1 cp -v ./*.page
-
文件会被逐个复制到两个目录中,
cp
命令会显示出每个文件的复制操作过程,让我们可以清晰地看到操作执行的过程
删除嵌套目录中的文件
-
如果文件名中有空格或者特殊字符(如换行符),
xargs
命令可能将无法被正确解析。我们可以使用-0
(空终止符)选项来解决此问题,这个选项会告诉xargs
命令使用空字符作为文件名的终止分隔符 -
我们将在这个示列中使用
find
命令。find
自带专门处理文件名中有空格和特殊字符的选项。即-print0
(full name, null character)选项find . -name "*.png" -type f -print0 | xargs -0 rm -v -rf "{}"
-
具体分解如下:
find . -name "*.png"
:find
命令将会从当前目录"."
中进行搜索,查找所有名称和"*.png"
相匹配的文件,并且文件的类型为(-type f)普通文件-print0
:输出的文件名将以空字符(null)作为终止符,并且确保能够正确的去处理含有空格和特殊字符的情况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
命令在当前目录进行递归搜索名为"leve_one"的目录,并且将搜索的结果通过xargs
传递给rm
命令进行删除 -
这个命令与前一个命令的关键区别在于:搜索条件是顶层目录名,并且
-type d
参数告诉find
命令只查找目录,而不是文件
-
在删除每个目录时其名称都会被打印出来,我们可以使用
tree
命令进行检验:tree -d
-
所有的嵌套子目录都会被删除
删除其余所有文件,除了要保留的指定文件
-
我们可以通过组合使用
find
,xargs
和rm
命令实现我们想要保留的特定类型文件并且删除其余所有文件的操作。虽然逻辑看起来很矛盾,但实际需要指定的时我们自己希望所保留的文件类型,而不是要删除的类型 -
-not
选项告诉find
指令返回不符合搜索模式的文件名。当我们再次使用xargs
命令的-l
(initial arguments)选项,此次定义的替换字符串被我们定义为"{}"
,它的功能与之前使用的"%"
符号完全一致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
命令都包含大量的功能选项,你可以积极地去查阅它们的功能手册以获得完整的使用说明