bash 带有多个命令的 xargs
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18731610/
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
xargs with multiple commands
提问by user987654
In the current directory, I'd like to print the filename and contents in it. I can print filenames or contents separately by
在当前目录中,我想打印其中的文件名和内容。我可以分别打印文件名或内容
find . | grep "file_for_print" | xargs echo
find . | grep "file_for_print" | xargs cat
but what I want is printing them together like this:
但我想要的是像这样将它们打印在一起:
file1
line1 inside file1
line2 inside file1
file2
line1 inside file2
line2 inside file2
I read xargs with multiple commands as argumentand tried
find . | grep "file_for_print" | xargs -I % sh -c 'echo; cat;'
but doesn't work. I'm not familiar with xargs, so don't know what exactly "-I % sh -c" means. could anyone help me? thank you!
但不起作用。我不熟悉 xargs,所以不知道“-I % sh -c”究竟是什么意思。有人可以帮助我吗?谢谢你!
回答by necromancer
find . | grep "file_for_print" | xargs -I % sh -c 'echo %; cat %;'
(OP was missing %
s)
find . | grep "file_for_print" | xargs -I % sh -c 'echo %; cat %;'
(OP 缺少%
s)
回答by rici
To start with, there is virtually no difference between:
首先,以下之间几乎没有区别:
find . | grep "file_for_print" | xargs echo
and
和
find . -name "file_for_print*"
except that the second one will not match filenames like this_is_not_the_file_for_print
, and it will print the filenames one per line. It will also be a lot faster, because it doesn't need to generate and print the entire recursive directory structure just in order for grep to toss most of it away.
除了第二个将不匹配文件名,如this_is_not_the_file_for_print
,它将每行打印一个文件名。它也会快很多,因为它不需要生成和打印整个递归目录结构,只是为了让 grep 将大部分内容扔掉。
find . -name "file_for_print*"
is actually exactly the same as
实际上完全一样
find . -name "file_for_print*" -print
where the -print
action prints each matched filename followed by a newline. If you don't provide find
with any actions, it assumes you wanted -print
. But it has more tricks up its sleeve than that. For example:
该-print
操作打印每个匹配的文件名,后跟换行符。如果您不提供find
任何操作,则假定您想要-print
. 但它有更多的技巧。例如:
find . -name "file_for_print*" -exec cat {} \;
The -exec
action causes find to execute the following command, up to the \;
, replacing {}
with each matching file name.
该-exec
操作导致 find 执行以下命令,直到\;
, 替换{}
为每个匹配的文件名。
find
does not limit itself to a single action. You can tell it to do however many you want. So:
find
不限于单个动作。你可以告诉它做任何你想做的事。所以:
find . -name "file_for_print*" -print -exec cat {} \;
will probably do pretty well what you want.
可能会很好地完成你想要的。
For lots more information on this very useful utility, type:
有关此非常有用的实用程序的更多信息,请键入:
man find
or
或者
info find
and read all about It.
并阅读有关它的所有内容。
回答by dshepherd
Since it's not been said yet: -I %
tells xargs to replace '%' with the arguments in the command you give it. The sh -c '...'
just means run the commands '...'
in a new shell.
因为还没有说:-I %
告诉 xargs 用你给它的命令中的参数替换 '%'。在sh -c '...'
刚刚手段运行的命令'...'
在新壳。
So
所以
xargs -I % sh -c 'echo %; cat %;'
will run echo [filename]
followed by cat [filename]
for every filename given to xargs
. The echo and cat commands will be executed inside a different shell process but this usually doesn't matter. Your version didn't work because it was missing the %
signs inside the command passed to xargs
.
将运行,echo [filename]
然后cat [filename]
为给定的每个文件名运行xargs
。echo 和 cat 命令将在不同的 shell 进程中执行,但这通常无关紧要。您的版本不起作用,因为它缺少%
传递给xargs
.
For what it's worth I would use this command to achieve the same thing:
对于它的价值,我会使用这个命令来实现同样的事情:
find -name "*file_for_print*" | parallel 'echo {}; cat {};'
because it's simpler (parallel
automatically uses {}
as the substitution character and can take multiple commands by default).
因为它更简单(parallel
自动{}
用作替换字符,默认情况下可以使用多个命令)。
回答by tavvit
In this specific case, each command is executed for each individual file anyway, so there's no advantage in using xargs. You may just append -exec twice to your 'find':
在这种特定情况下,无论如何都会为每个单独的文件执行每个命令,因此使用 xargs 没有任何优势。您可以将 -exec 两次附加到您的“查找”:
find . -name "*file_for_print*" -exec echo {} \; -exec cat {} \;
In this case-print
could be used instead of the first echo
as pointed out by rici, but this example shows the ability to execute two arbitrary commands with a single find
在这种情况下-print
,可以使用echo
rici 所指出的代替第一个,但此示例显示了使用单个命令执行两个任意命令的能力find
回答by Aleks-Daniel Jakimenko-A.
What about writing your own bash function?
编写自己的 bash 函数怎么样?
#!/bin/bash
myFunction() {
while read -r file; do
echo "$file"
cat "$file"
done
}
find . -name "file_for_print*" | myFunction