cat a.txt | xargs -I % echo %
在上面的例子中,xargs使用echo %作为命令参数。但在某些情况下,我需要多个命令来处理参数,而不是一个。例如:
cat a.txt | xargs -I % {command1; command2; ... }
但是xargs不接受这种形式。我知道的一种解决方案是,我可以定义一个函数来包装命令,但我想避免这样做,因为它很复杂。有没有更好的解决方案?
cat a.txt | xargs -I % echo %
在上面的例子中,xargs使用echo %作为命令参数。但在某些情况下,我需要多个命令来处理参数,而不是一个。例如:
cat a.txt | xargs -I % {command1; command2; ... }
但是xargs不接受这种形式。我知道的一种解决方案是,我可以定义一个函数来包装命令,但我想避免这样做,因为它很复杂。有没有更好的解决方案?
当前回答
对我来说另一个可行的解决方案是——
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
其他回答
cat a.txt | xargs -d $'\n' sh -c 'for arg do command1 "$arg"; command2 "$arg"; ...; done' _
...或者,不用无用地使用cat:
<a.txt xargs -d $'\n' sh -c 'for arg do command1 "$arg"; command2 "$arg"; ...; done' _
来解释一些细节:
The use of "$arg" instead of % (and the absence of -I in the xargs command line) is for security reasons: Passing data on sh's command-line argument list instead of substituting it into code prevents content that data might contain (such as $(rm -rf ~), to take a particularly malicious example) from being executed as code. Similarly, the use of -d $'\n' is a GNU extension which causes xargs to treat each line of the input file as a separate data item. Either this or -0 (which expects NULs instead of newlines) is necessary to prevent xargs from trying to apply shell-like (but not quite shell-compatible) parsing to the stream it reads. (If you don't have GNU xargs, you can use tr '\n' '\0' <a.txt | xargs -0 ... to get line-oriented reading without -d). The _ is a placeholder for $0, such that other data values added by xargs become $1 and onward, which happens to be the default set of values a for loop iterates over.
对我来说另一个可行的解决方案是——
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
这是另一种没有xargs和cat的方法:
while read stuff; do
command1 "$stuff"
command2 "$stuff"
...
done < a.txt
试试这个:
git config --global alias.all '!f() { find . -d -name ".git" | sed s/\\/\.git//g | xargs -P10 -I{} git --git-dir={}/.git --work-tree={} $1; }; f'
它并行运行10个线程,并执行任何你想要在文件夹结构中全部回购的git命令。无论回购是1层还是n层。
例句:get all pull
我更喜欢允许试运行模式的样式(没有| sh):
cat a.txt | xargs -I % echo "command1; command2; ... " | sh
管道也适用:
cat a.txt | xargs -I % echo "echo % | cat " | sh