如何将命令输出作为多个parameter passing给另一个命令
我想把一个命令的每个输出作为多个parameter passing给另一个命令,例如:
grep "pattern" input
收益:
file1 file2 file3
我想复制这些输出,例如:
cp file1 file1.bac cp file2 file2.bac cp file3 file3.bac
我怎样才能一次做到这一点? 就像是:
grep "pattern" input | cp $1 $1.bac
你可以使用xargs
:
grep 'pattern' input | xargs -I% cp "%" "%.bac"
您可以使用$()
插入命令的输出。 因此,您可以使用kill -9 $(grep -hP '^\d+$' $(ls -lad /dir/*/pid | grep -P '/dir/\d+/pid' | awk '{ print $9 }'))
如果你想。
除了克里斯·杰斯特·杨(Chris Jester-Young)的回答 ,我会说xargs
对于这些情况也是一个很好的解决scheme:
grep ... `ls -lad ... | awk '{ print $9 }'` | xargs kill -9
会做到的。 全部一起:
grep -hP '^\d+$' `ls -lad /dir/*/pid | grep -P '/dir/\d+/pid' | awk '{ print $9 }'` | xargs kill -9
为了完整起见,我还会提到命令replace, 并解释为什么不推荐这样做:
cp $(grep -l "pattern" input) directory/
(反引号语法cp `grep -l "pattern" input` directory/
大致相当,但已经过时和笨拙;不要使用它。)
如果grep
的输出产生一个包含空格或者shell元字符的文件名,这将会失败。
当然,如果你确切地知道grep
能够产生哪个文件名,就可以使用它,并且已经validation了它们都没有问题。 但是对于生产脚本, 不要使用这个。
无论如何,对于OP的情况,你需要单独地引用每个匹配并为它添加一个扩展名, xargs
或者while read
select是优越的。
在最坏的情况下(意思是有问题或未指定的文件名),通过xargs
将匹配传递给子shell:
grep -l "pattern" input | xargs -r sh -c 'for f; do mv "$f" "$f.bac"; done' _
…显然, for
循环内部的脚本可能是任意复杂的。