cat a.txt | xargs -I % echo %
Run Code Online (Sandbox Code Playgroud)
在上面的示例中,xargs echo %用作命令参数.但在某些情况下,我需要多个命令来处理参数而不是一个.例如:
cat a.txt | xargs -I % {command1; command2; ... }
Run Code Online (Sandbox Code Playgroud)
但是xargs不接受这种形式.我知道的一个解决方案是我可以定义一个函数来包装命令,但它不是一个管道,我不喜欢它.还有其他解决方案吗?
Kei*_*son 414
cat a.txt | xargs -d $'\n' sh -c 'for arg do command1 "$arg"; command2 "$arg"; ...; done' _
Run Code Online (Sandbox Code Playgroud)
请注意,这是一种无用的猫.我把它写成:
<a.txt xargs -d $'\n' sh -c 'for arg do command1 "$arg"; command2 "$arg"; ...; done' _
Run Code Online (Sandbox Code Playgroud)
(是的,重定向可以在命令的开头.)
据推测"$arg"和/或%将包含一个或多个-I字符; 否则就不会有太大指向xargs选项sh.
Ole*_*nge 34
使用GNU Parallel,您可以:
cat a.txt | parallel 'command1 {}; command2 {}; ...; '
Run Code Online (Sandbox Code Playgroud)
观看介绍视频以了解更多信息:https://www.youtube.com/playlist?list = PL284C9FF2488BC6D1
hmo*_*liu 24
这只是没有xargs和cat的另一种方法:
while read stuff; do
command1 "$stuff"
command2 "$stuff"
...
done < a.txt
Run Code Online (Sandbox Code Playgroud)
小智 21
您可以使用
cat file.txt | xargs -i sh -c 'command {} | command2 {} && command3 {}'
Run Code Online (Sandbox Code Playgroud)
{} =文本文件中每一行的变量
小智 15
我做的一件事是添加.bashrc/.profile这个函数:
function each() {
while read line; do
for f in "$@"; do
$f $line
done
done
}
Run Code Online (Sandbox Code Playgroud)
然后你可以做的事情
... | each command1 command2 "command3 has spaces"
Run Code Online (Sandbox Code Playgroud)
它比xargs或-exec更简洁.如果您还需要该行为,您还可以修改函数以将读取的值插入命令中的任意位置.
sdk*_*kks 12
派对有点晚了.
我使用下面的格式在迁移之前用数千个小文件压缩我的目录.如果您在命令中不需要单引号,它应该可以工作.
经过一些修改,我确信它对某人有用.测试Cygwin(babun)
find . -maxdepth 1 ! -path . -type d -print0 | xargs -0 -I @@ bash -c '{ tar caf "@@.tar.lzop" "@@" && echo Completed compressing directory "@@" ; }'
Run Code Online (Sandbox Code Playgroud)
find .在此处查找
-maxdepth 1不要进入子目录
! -path .排除./当前目录路径
-type d仅匹配目录
-print0以空字节分隔输出\ 0
| xargs管道到xargs
-0输入为空分隔字节
-I @@占位符为@@.用输入替换@@.
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
Run Code Online (Sandbox Code Playgroud)
2018年7月更新:
如果你喜欢黑客和玩耍,这里有一些有趣的东西:
echo "a b c" > a.txt
echo "123" >> a.txt
echo "###this is a comment" >> a.txt
cat a.txt
myCommandWithDifferentQuotes=$(cat <<'EOF'
echo "command 1: $@"; echo 'will you do the fandango?'; echo "command 2: $@"; echo
EOF
)
< a.txt xargs -I @@ bash -c "$myCommandWithDifferentQuotes" -- @@
Run Code Online (Sandbox Code Playgroud)
输出:
command 1: a b c
will you do the fandango?
command 2: a b c
command 1: 123
will you do the fandango?
command 2: 123
command 1: ###this is a comment
will you do the fandango?
command 2: ###this is a comment
Run Code Online (Sandbox Code Playgroud)
说明:
-创建一个单一的衬垫脚本,并将其存储在一个变量
- xargs读取a.txt并执行它作为bash脚本
- @@确保整条生产线是通过每一次
-把@@后--确保@@被视为位置参数输入bash命令,而不是一个bash开始OPTION,即喜欢-c自己的意思run command
--是神奇的,它适用于许多其他的东西,即ssh,甚至kubectl
bra*_*blc 11
我更喜欢允许干运行模式的风格(没有| sh):
cat a.txt | xargs -I % echo "command1; command2; ... " | sh
Run Code Online (Sandbox Code Playgroud)
也适用于管道:
cat a.txt | xargs -I % echo "echo % | cat " | sh
Run Code Online (Sandbox Code Playgroud)
小智 7
对我有用的另一个可能的解决方案是 -
cat a.txt | xargs bash -c 'command1 $@; command2 $@' bash
Run Code Online (Sandbox Code Playgroud)
注意最后的'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
Run Code Online (Sandbox Code Playgroud)
这似乎是最安全的版本。
tr '[\n]' '[\0]' < a.txt | xargs -r0 /bin/bash -c 'command1 "$@"; command2 "$@";' ''
Run Code Online (Sandbox Code Playgroud)
(-0可以删除并tr用重定向替换(或该文件可以用空分隔的文件代替)。它主要在此,因为我主要xargs与findwith -print0输出配合使用)(这也可能与xargs没有-0扩展名的版本有关)
这是安全的,因为args在执行时会将参数作为数组传递给Shell。bash然后,当使用以下命令获取所有内容时,shell(至少)会将它们作为未更改的数组传递给其他进程["$@"][1]
如果使用...| xargs -r0 -I{} bash -c 'f="{}"; command "$f";' '',则在字符串包含双引号的情况下分配将失败。对于使用-i或的每个变体来说都是如此-I。(由于将其替换为字符串,您始终可以通过在输入数据中插入意外字符(如引号,反引号或美元符号)来注入命令)
如果这些命令一次只能使用一个参数:
tr '[\n]' '[\0]' < a.txt | xargs -r0 -n1 /bin/bash -c 'command1 "$@"; command2 "$@";' ''
Run Code Online (Sandbox Code Playgroud)
或使用较少的流程:
tr '[\n]' '[\0]' < a.txt | xargs -r0 /bin/bash -c 'for f in "$@"; do command1 "$f"; command2 "$f"; done;' ''
Run Code Online (Sandbox Code Playgroud)
如果您具有GNU xargs或其他带有-P扩展名的文件,并且希望并行运行32个进程,则每个命令的每个参数不得超过10个:
tr '[\n]' '[\0]' < a.txt | xargs -r0 -n10 -P32 /bin/bash -c 'command1 "$@"; command2 "$@";' ''
Run Code Online (Sandbox Code Playgroud)
对于输入中的任何特殊字符,这应该是可靠的。(如果输入为null分隔。)tr如果某些行包含换行符,则版本将获得一些无效的输入,但是对于换行符分隔的文件,这是不可避免的。
的空白第一个参数bash -c是由于以下原因:(来自bash手册页)(感谢@clacke)
-c If the -c option is present, then commands are read from the first non-option argument com?
mand_string. If there are arguments after the command_string, the first argument is assigned to $0
and any remaining arguments are assigned to the positional parameters. The assignment to $0 sets
the name of the shell, which is used in warning and error messages.
Run Code Online (Sandbox Code Playgroud)