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

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

xargs with multiple commands

bashxargs

提问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

用多个命令作为参数读取xargs并尝试

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 -printaction prints each matched filename followed by a newline. If you don't provide findwith 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 -execaction causes find to execute the following command, up to the \;, replacing {}with each matching file name.

-exec操作导致 find 执行以下命令,直到\;, 替换{}为每个匹配的文件名。

finddoes 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 (parallelautomatically 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-printcould be used instead of the first echoas pointed out by rici, but this example shows the ability to execute two arbitrary commands with a single find

在这种情况下-print,可以使用echorici 所指出的代替第一个,但此示例显示了使用单个命令执行两个任意命令的能力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