Linux 命令输出作为另一个命令的参数

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/13236344/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 17:42:18  来源:igfitidea点击:

Linux command output as a parameter of another command

linuxparameterscommandpipe

提问by Luis Andrés García

I would like to pass the output list of elements of a command as a parameter of another command. I have found some other pages:

我想将命令元素的输出列表作为另一个命令的参数传递。我找到了一些其他页面:

but they seem to be more complex.

但它们似乎更复杂。

I just would like to copy a file to every result of a call to the Linux findcommand.

我只想将文件复制到调用 Linuxfind命令的每个结果。

What is wrong here?:

这里有什么问题?:

find . -name myFile 2>&1 | cp /home/myuser/myFile 

Thanks

谢谢

采纳答案by sampson-chen

This is what you want:

这就是你想要的:

find . -name myFile -exec cp /home/myuser/myFile {} ';'

A breakdown / explanation of this:

对此的细分/解释:

  • find: invoking the find command
  • .: start search from current working directory.
  • Since no depth flags are specified, this will search recursively for all subfolders
  • -name myFile: find files with the explicit name myFile
  • -exec: for the search results, perform additional commands with them
  • cp /home/myuser/myFile {}: copies /home/myuser/myFileto overwrite each result returned by findto ; think of {}as where each search result goes.
  • ';': used to separate different commands to be run after find
  • find: 调用 find 命令
  • .: 从当前工作目录开始搜索。
  • 由于没有指定深度标志,这将递归搜索所有子文件夹
  • -name myFile: 查找具有明确名称的文件 myFile
  • -exec:对于搜索结果,使用它们执行其他命令
  • cp /home/myuser/myFile {}: 复制/home/myuser/myFile以覆盖findto返回的每个结果;想想{}每个搜索结果的去向。
  • ';': 用于分隔要运行的不同命令 find

回答by Brian Cain

The pipe will send the output of one program to the input of another. cpdoes not read from its input stream at the terminal, it merely uses the arguments on the command line.

管道将一个程序的输出发送到另一个程序的输入。 cp不在终端从其输入流中读取,它仅使用命令行上的参数。

You want to either use xargswith the pipe or find's execargument instead of pipes.

您想xargs与管道或findexec参数一起使用而不是管道。

回答by Brian Campbell

There are a couple of ways to solve this, depending on whether you need to worry about files with spaces or other special characters in their names.

有几种方法可以解决此问题,具体取决于您是否需要担心名称中包含空格或其他特殊字符的文件。

If none of the filenames have spaces or special characters (they consist only of letters, numbers, dashes, and underscores), then the following is a simple solution that will work. You can use $(command)to execute a command, and substitute the results into the arguments of another command. The shell will split the result on spaces, tabs, or newlines, and forassign each value to $fin turn, and run the command on each value.

如果文件名中没有空格或特殊字符(它们仅由字母、数字、破折号和下划线组成),那么以下是一个可行的简单解决方案。您可以使用$(command)来执行一个命令,并将结果替换为另一个命令的参数。shell 会将结果拆分为空格、制表符或换行符,并依次for分配每个值,并对每个值$f运行命令。

for f in $(find . -name myFile)
do
    cp something $f
done

If you do have spaces or tabs, you could use find's -execoption. You pass -exec command args, putting {}where you want the filename to be substituted, and ending the arguments with a ;. You need to quote the {}and ;so that the shell doesn't interpret them.

如果您确实有空格或制表符,则可以使用 find 的-exec选项。您通过-exec command args,将{}文件名放在您想要替换的位置,并以;. 您需要引用{}and;以便外壳不会解释它们。

find . -name myFile -exec cp something "{}" \;

Sometimes -execis not sufficient. For example, in this question, they wanted to use Bash parameter expansion to compute the filename. In order to do that, you need to pass -exec bash -c 'your command', but then you will run into quoting problems with the {}substitution. To solve this, you can use -print0from findto print the results delimited with null characters (which are invalid in filenames), and pipe it to a while readloop that splits parameters on nulls:

有时-exec是不够的。例如,在这个问题中,他们想使用 Bash 参数扩展来计算文件名。为了做到这一点,您需要通过-exec bash -c 'your command',但随后您将遇到{}替换的引用问题。要解决此问题,您可以使用-print0fromfind打印以空字符(在文件名中无效)分隔的结果,并将其通过管道传输到while read将参数拆分为空值的循环:

find . -name myFile -print0 | (while read -d $'##代码##' f; do
    cp something "$f"
  done)