Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linux 如何将命令输出作为多个参数传递给另一个命令_Linux_Shell_Unix - Fatal编程技术网

Linux 如何将命令输出作为多个参数传递给另一个命令

Linux 如何将命令输出作为多个参数传递给另一个命令,linux,shell,unix,Linux,Shell,Unix,我希望将命令的每个输出作为多个参数传递给第二个命令,例如: 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 您可以使用$()插入命令的输出。因此,如果您愿意,您可以使用kill-9$(grep-hP'^\d

我希望将命令的每个输出作为多个参数传递给第二个命令,例如:

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
您可以使用
$()
插入命令的输出。因此,如果您愿意,您可以使用
kill-9$(grep-hP'^\d+$(ls-lad/dir/*/pid | grep-P'/dir/\d+/pid'{124; awk'{print$9}')

此外,我想说

xargs
对于这些情况也是一个很好的解决方案:

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

您可以使用
xargs

grep 'pattern' input | xargs -I% cp "%" "%.bac"
grep -l "pattern" input |
xargs -r sh -c 'for f; do cp "$f" "$f.bac"; done' _

为了完整起见,我还将提到命令替换,并解释为什么不建议使用此方法:

(backtick语法
cp`grep-l“pattern”input`directory/
大致相当,但它已经过时且难以使用;不要使用它。)

如果
grep
的输出生成包含空格或shell元字符的文件名,则此操作将失败

当然,如果您确切地知道
grep
可以生成哪些文件名,并且已经验证了这些文件名都没有问题,那么就可以使用它。但对于制作脚本,不要使用此选项。

无论如何,在OP的场景中,您需要单独引用每个匹配项并为其添加扩展名,
xargs
while read
选项无论如何都是优越的

在最坏的情况下(意味着有问题或未指定的文件名),通过
xargs
将匹配项传递给子shell:

grep 'pattern' input | xargs -I% cp "%" "%.bac"
grep -l "pattern" input |
xargs -r sh -c 'for f; do cp "$f" "$f.bac"; done' _
。。。显然,
for
循环中的脚本可能是任意复杂的

在理想情况下,您想要运行的命令非常简单(或通用),您可以简单地向其传递任意长的文件名列表。例如,GNU
cp
有一个
-t
选项,以便于使用
xargs
(使用
-t
选项可以将目标目录放在命令行的第一位,因此可以在命令末尾放置任意数量的文件):

这将扩展到

cp -t destdir file1 file2 file3 file4 ...
对于
xargs
可以放入
cp
的命令行的匹配项,重复多次以将所有文件传递到
cp
。(不幸的是,这与OP的场景不匹配;如果需要在复制时重命名每个文件,则只需在每个
cp
调用中传入两个参数:源文件名和要复制到的目标文件名。)

因此,换句话说,如果您使用命令替换语法并且
grep
生成了一个非常长的匹配列表,那么您可能会遇到“参数列表太长”错误;但是
xargs
将通过一次只复制尽可能多的参数以安全地传递给
cp
,并在必要时多次运行
cp
来避免这种情况

#!/bin/bash

for f in files; do
  if grep -q PATTERN "$f"; then
    echo cp -v "$f" "${f}.bac"
  fi
done

文件可以是*.txt或*.text,这基本上意味着以*.txt或*.text结尾的文件,或者替换为您想要/需要的文件,当然用您的替换模式。如果您对输出满意,请删除echo。对于递归解决方案,请查看bashshell选项globstar

使用命令
xargs
。我猜您的意思是
grep-l
。。。或者,
input
包含一个文件名列表,您希望对其中的一个子集进行grep。另请参见其中的详细说明。