在当前目录中,我想打印文件名和内容。 我可以通过
单独打印文件名或内容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”的意思。 谁能帮助我?谢谢!
答案 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
执行两个任意命令的能力