用多个命令作为参数的xargs
cat a.txt | xargs -I % echo %
在上面的例子中,xargs将echo %
作为命令参数。 但在某些情况下,我需要多个命令来处理,而不是一个,例如:
cat a.txt | xargs -I % {command1; command2; ... }
但是xargs不接受这种forms。 我知道的一个解决scheme是我可以定义一个函数来封装这些命令,但它不是pipe道,我不喜欢它。 还有其他解决scheme吗?
cat a.txt | xargs -I % sh -c 'command1; command2; ...'
请注意,这是一个无用的猫 。 我会把它写成:
< a.txt xargs -I % sh -c 'command1; command2; ...'
(是的,redirect可以在命令的开头。)
假定command1
和/或command2
将包含一个或多个%
字符; 否则就不会有太多的指向xargs
的-I %
选项。
使用GNU Parallel,您可以执行以下操作:
cat a.txt | parallel 'command1 {}; command2 {}; ...; '
观看介绍video以了解更多信息: https : //www.youtube.com/playlist?list = PL284C9FF2488BC6D1
Keith答案是+1
,因为它符合OP的要求。
这只是没有xargs和cat的另一种方法:
while read stuff; do command1 "$stuff" command2 "$stuff" ... done < a.txt
我做的一件事是添加到.bashrc / .profile这个函数:
function each() { while read line; do for f in "$@"; do $f $line done done }
那么你可以做类似的事情
... | each command1 command2 "command3 has spaces"
这比xargs或-exec的冗长。 如果你还需要这个行为的话,你也可以修改这个函数来把读取的值插入到命令的任意位置。
您可以使用
cat file.txt | xargs -i sh -c 'command {} | command2 {} && command3 {}'
{} =文本文件上每行的variables
另一个可行的解决scheme,对我来说是类似的 –
cat a.txt | xargs bash -c 'command1 $@; command2 $@' bash
注意最后的“bash” – 我认为它是作为argv [0]传递给bash的。 如果没有这个语法,每个命令的第一个参数就会丢失。 这可能是任何单词。
例:
cat a.txt | xargs -n 5 bash -c 'echo -n `date +%Y%m%d-%H%M%S:` ; echo " data: " $@; echo "data again: " $@' bash
晚会有点迟。
我使用下面的格式在迁移前用成千上万的小文件压缩我的目录。 如果你不需要单引号里面的命令,它应该工作。
经过一些修改,我相信这对别人有用。 在Cygwin
(babun)testing
find . -maxdepth 1 ! -path . -type d -print0 | xargs -0 -I @@ bash -c '{ tar caf "@@.tar.lzop" "@@" && echo Completed compressing directory "@@" ; }'
find .
在这里find
-maxdepth 1
不要进入子目录
! -path .
排除。 /当前目录path
-type d
只匹配目录
-print0
以空字节\ 0分隔输出
| xargs
| xargs
pipe道xargs
-0
input是空分隔的字节
-I @@
占位符是@@。 用inputreplace@@。
bash -c '...'
运行Bash命令
{...}
命令分组
&&
仅当前一个命令成功退出时才执行下一个命令(退出0)
决赛 很重要,否则会失败。
输出:
Completed compressing directory ./Directory1 with meta characters in it Completed compressing directory ./Directory2 with meta characters in it Completed compressing directory ./Directory3 with meta characters in it
我现在的BKM是这样的
... | xargs -n1 -I % perl -e 'system("echo 1 %"); system("echo 2 %");'
不幸的是,这使用perl,这是不太可能安装比bash; 但它处理更多的input,接受的答案。 (我欢迎一个不依赖perl的无处不在的版本。)
基思·汤普森的build议
... | xargs -I % sh -c 'command1; command2; ...'
非常棒 – 除非在input中有shell注释字符#,在这种情况下,第一个命令的一部分和第二个命令的全部将被截断。
如果input来自文件系统列表(例如ls或find),并且编辑器使用名称中的#创build临时文件,那么散列#就相当普遍。
问题的例子:
$ bash 1366 $> /bin/ls | cat #Makefile# #README# Makefile README
哎呀,这是问题所在:
$ bash 1367 $> ls | xargs -n1 -I % sh -i -c 'echo 1 %; echo 2 %' 1 1 1 1 Makefile 2 Makefile 1 README 2 README
啊,那好些
$ bash 1368 $> ls | xargs -n1 -I % perl -e 'system("echo 1 %"); system("echo 2 %");' 1 #Makefile# 2 #Makefile# 1 #README# 2 #README# 1 Makefile 2 Makefile 1 README 2 README $ bash 1369 $>
我更喜欢风格,允许空运行模式(没有| sh
):
cat a.txt | xargs -I % echo "command1; command2; ... " | sh
与pipe道一起工作:
cat a.txt | xargs -I % echo "echo % | cat " | sh