带有多个命令的xargs

时间:2013-09-11 02:12:14

标签: bash xargs

在当前目录中,我想打印文件名和内容。 我可以通过

单独打印文件名或内容
find . | grep "file_for_print" | xargs echo
find . | grep "file_for_print" | xargs cat

但我想要的是将它们打印在一起:

file1
line1 inside file1
line2 inside file1
file2
line1 inside file2
line2 inside file2

我看了xargs with multiple commands as argument 并试过

find . | grep "file_for_print" | xargs -I % sh -c 'echo; cat;'

但不起作用。 我不熟悉xargs,所以不知道究竟是什么“-I%sh -c”的意思。 谁能帮助我?谢谢!

5 个答案:

答案 0 :(得分:20)

find . | grep "file_for_print" | xargs -I % sh -c 'echo %; cat %;'(OP缺少% s)

答案 1 :(得分:13)

首先,实际上没有区别:

find . | grep "file_for_print" | xargs echo

find . -name "file_for_print*"

除了第二个文件名与this_is_not_the_file_for_print之类的文件名不匹配,它将每行打印一个文件名。它也会快得多,因为它不需要生成和打印整个递归目录结构,只是为了让grep将大部分内容扔掉。

find . -name "file_for_print*"

实际上与

完全相同
find . -name "file_for_print*" -print

其中-print操作打印每个匹配的文件名后跟换行符。如果您未向find提供任何操作,则会假定您需要-print。但它有更多的伎俩。例如:

find . -name "file_for_print*" -exec cat {} \;

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

find并不局限于单一操作。无论你想要多少,你都可以告诉它。所以:

find . -name "file_for_print*" -print -exec cat {} \;

可能会做得很好。

有关此非常有用的实用程序的更多信息,请键入:

man find

info find

阅读所有关于它的信息。

答案 2 :(得分:9)

因为还没有说过:-I %告诉xargs用您给出的命令中的参数替换'%'。 sh -c '...'只意味着在新shell中运行命令'...'

所以

xargs -I % sh -c 'echo %; cat %;'
对于echo [filename]的每个文件名,

将运行cat [filename]后跟xargs。 echo和cat命令将在不同的shell进程中执行,但这通常无关紧要。您的版本无效,因为它错过了传递给%的命令中的xargs个符号。


为了它的价值,我会用这个命令来实现同样的目的:

find -name "*file_for_print*" | parallel 'echo {}; cat {};'

因为它更简单(parallel自动使用{}作为替换字符,默认情况下可以使用多个命令。)

答案 3 :(得分:0)

编写自己的bash函数怎么样?

#!/bin/bash

myFunction() {
    while read -r file; do
        echo "$file"
        cat "$file"
    done
}

find . -name "file_for_print*" | myFunction

答案 4 :(得分:0)

在这种特定情况下,无论如何都会为每个单独的文件执行每个命令,因此使用xargs没有任何优势。你可以在你的'find'中附加-exec两次:

find . -name "*file_for_print*" -exec echo {} \; -exec cat {} \;

在这种情况下,可以使用-print代替rici指出的第一个echo,但是此示例显示了使用单个find执行两个任意命令的能力