15

在当前目录中,我想打印其中的文件名和内容。我可以分别打印文件名或内容

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 并尝试了

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

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

4

5 回答 5

30

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

于 2013-09-11T02:29:28.023 回答
14

首先,以下之间几乎没有区别:

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

并阅读有关它的所有信息。

于 2013-09-11T02:26:03.713 回答
10

因为它还没有被说出来:-I %告诉 xargs 用你给它的命令中的参数替换 '%'。sh -c '...'just 意味着在新的 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自动{}用作替换字符并且默认情况下可以采用多个命令)。

于 2014-02-07T11:23:01.320 回答
2

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

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

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

于 2014-02-12T08:04:34.453 回答
0

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

#!/bin/bash

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

find . -name "file_for_print*" | myFunction
于 2013-09-11T15:39:27.233 回答