it_*_*ure 232 shell find xargs
$ ls *mp3 | xargs mplayer  
Playing Lemon.  
File not found: 'Lemon'  
Playing Tree.mp3.  
File not found: 'Tree.mp3'  
Exiting... (End of file)  
我的命令失败,因为文件"Lemon Tree.mp3"包含空格,因此xargs认为它是两个文件.我可以使find + xargs使用这样的文件名吗?
Ray*_*Ray 219
该xargs命令将空格字符(制表符,空格,换行符)作为分隔符.您可以使用以下-d选项将其缩小到仅适用于新行字符('\n'):
ls *.mp3 | xargs -d '\n' mplayer
它仅适用于GNU xargs.对于BSD系统,请使用如下-0选项:
ls *.mp3 | xargs -0 mplayer
这种方法更简单,也适用于GNU xargs.
Jen*_*ens 206
xargs实用程序从标准输入读取空格,制表符,换行符和文件结尾分隔符,并以字符串作为参数执行实用程序.
您希望避免使用空格作为分隔符.这可以通过更改xargs的分隔符来完成.根据手册:
Run Code Online (Sandbox Code Playgroud)-0 Change xargs to expect NUL (``\0'') characters as separators, instead of spaces and newlines. This is expected to be used in concert with the -print0 function in find(1).
如:
 find . -name "*.mp3" -print0 | xargs -0 mplayer
回答关于播放每七个mp3的问题; 它运行起来比较简单
 mplayer "$(ls *.mp3 | sed -n 7p)"
Sco*_*son 25
尝试
find . -name \*.mp3 -print0 | xargs -0 mplayer
代替
ls | grep mp3 
Gra*_*yle 12
MacOS上的xargs没有-d选项,因此该解决方案使用-0代替.
获取ls每行输出一个文件,然后将换行符转换为空值并告诉xargs使用空值作为分隔符:
ls -1 *mp3 | tr "\n" "\0" | xargs -0 mplayer
我知道我没有xargs直接回答这个问题,但值得一提的find是 的-exec选项。
给定以下文件系统:
[root@localhost bokeh]# tree --charset assci bands
bands
|-- Dream\ Theater
|-- King's\ X
|-- Megadeth
`-- Rush
0 directories, 4 files
find 命令可以用来处理 Dream Theater 和 King's X 中的空间。因此,使用 grep 查找每个乐队的鼓手:
[root@localhost]# find bands/ -type f -exec grep Drums {} +
bands/Dream Theater:Drums:Mike Mangini
bands/Rush:Drums: Neil Peart
bands/King's X:Drums:Jerry Gaskill
bands/Megadeth:Drums:Dirk Verbeuren
-exec选项中{}代表包含路径的文件名。请注意,您不必转义它或将其放在引号中。
-exec的终止符(+和\;)之间的区别在于,+它可以将尽可能多的文件名分组到一个命令行上。而\;将为每个文件名执行命令。
所以,find bands/ -type f -exec grep Drums {} +会导致:
grep Drums "bands/Dream Theater" "bands/Rush" "bands/King's X" "bands/Megadeth"
并将find bands/ -type f -exec grep Drums {} \;导致:
grep Drums "bands/Dream Theater"
grep Drums "bands/Rush"
grep Drums "bands/King's X"
grep Drums "bands/Megadeth"
在这种情况下,grep会产生打印或不打印文件名的副作用。
[root@localhost bokeh]# find bands/ -type f -exec grep Drums {} \;
Drums:Mike Mangini
Drums: Neil Peart
Drums:Jerry Gaskill
Drums:Dirk Verbeuren
[root@localhost bokeh]# find bands/ -type f -exec grep Drums {} +
bands/Dream Theater:Drums:Mike Mangini
bands/Rush:Drums: Neil Peart
bands/King's X:Drums:Jerry Gaskill
bands/Megadeth:Drums:Dirk Verbeuren
当然,grep的选项-h和-H将控制是否打印文件名,无论如何grep调用。
xargsxargs还可以控制 man 文件在命令行上的显示方式。
xargs默认情况下将所有参数分组到一行。为了做同样的事情,-exec \;使用xargs -l. 请注意,该-t选项指示xargs在执行命令之前打印该命令。
[root@localhost bokeh]# find ./bands -type f  | xargs -d '\n' -l -t grep Drums
grep Drums ./bands/Dream Theater 
Drums:Mike Mangini
grep Drums ./bands/Rush 
Drums: Neil Peart
grep Drums ./bands/King's X 
Drums:Jerry Gaskill
grep Drums ./bands/Megadeth 
Drums:Dirk Verbeuren
看到该-l选项告诉 xargs 对每个文件名执行 grep。
与默认值(即无-l选项)相比:
[root@localhost bokeh]# find ./bands -type f  | xargs -d '\n'  -t grep Drums
grep Drums ./bands/Dream Theater ./bands/Rush ./bands/King's X ./bands/Megadeth 
./bands/Dream Theater:Drums:Mike Mangini
./bands/Rush:Drums: Neil Peart
./bands/King's X:Drums:Jerry Gaskill
./bands/Megadeth:Drums:Dirk Verbeuren
xargs可以更好地控制命令行上可以有多少文件。为该-l选项指定每个命令的最大文件数。
[root@localhost bokeh]# find ./bands -type f  | xargs -d '\n'  -l2 -t grep Drums
grep Drums ./bands/Dream Theater ./bands/Rush 
./bands/Dream Theater:Drums:Mike Mangini
./bands/Rush:Drums: Neil Peart
grep Drums ./bands/King's X ./bands/Megadeth 
./bands/King's X:Drums:Jerry Gaskill
./bands/Megadeth:Drums:Dirk Verbeuren
[root@localhost bokeh]# 
请注意,这grep是使用两个文件名执行的,因为-l2.
Dick.Guertin的回答[1]建议可以逃避文件名中的空格是这里建议的其他解决方案的有价值的替代方法(例如使用空字符作为分隔符而不是空格).但它可能更简单 - 你真的不需要一个独特的角色.您可以直接添加转义空格:
ls | grep ' ' | sed 's| |\\ |g' | xargs ...
此外,只有在您只需要名称中包含空格的文件时才需要grep .更一般地说(例如,当处理一批文件时,其中一些文件有空格,有些则没有),只需跳过grep:
ls | sed 's| |\\ |g' | xargs ...
然后,当然,文件名可能有空白而不是空格(例如,标签):
ls | sed -r 's|[[:blank:]]|\\\1|g' | xargs ...
这假设您有一个支持-r(扩展正则表达式)的sed,例如GNU sed或bsd sed的最新版本(例如,FreeBSD最初在FreeBSD 8之前拼写选项"-E"并支持-r和-E兼容)至少通过FreeBSD 11).否则,您可以使用基本的正则表达式字符类括号表达式,并在[]分隔符中手动输入空格和制表符.
[1]这可能更适合作为对该答案的评论或编辑,但目前我没有足够的声誉来评论,只能建议编辑.由于后面的形式(没有grep)改变了Dick.Guertin原始答案的行为,因此直接编辑可能不合适.
小智 5
find . -name 'Lemon*.mp3' -print0 | xargs -0 -i mplayer '{}' 
在我的情况下,这有助于删除带空格的不同文件.它应该与mplayer一起工作.必要的技巧是引号.(在Linux Xubuntu 14.04 上测试过.)
小智 5
在 macOS 10.12.x (Sierra) 上,如果文件名或子目录中有空格,可以使用以下命令:
find . -name '*.swift' -exec echo '"{}"' \; |xargs wc -l