我试图在目录(和所有子目录)中的所有文件中搜索字符串。如果文件具有该字符串,那么我想搜索另一个字符串出现的次数,在本例中为“snake”并输出它。我还想输出文件中出现“snake”的行。
echo "Files with Reptile:"
find . -type f -name "*.txt" -exec grep -l "Reptile" {} \;
我的挑战是如何在大括号后添加额外的 grep 命令。我尝试了一些方法,但不断收到“-exec 缺少参数”错误。
我是否试图在这个发现中塞入太多东西?
谢谢
答案1
您可以尝试以下操作:
$ find . -type f -name "*.txt" -exec sh -c "grep -l "Reptile" {} | xargs -I% grep -Hn snake %" \;
./rep1.txt:2:snake
./rep2.txt:5:another snake
输出包含以冒号分隔的列表,其中第一个参数是文件名(从参数-H
到grep
),第二个参数是所需术语出现的行号(从参数-n
到grep
),第三个参数是行本身。
可以xargs
移到 之外find
,为您提供:
$ find . -type f -name "*.txt" -exec grep -l "Reptile" {} \; | xargs -i grep -Hn snake {}
请注意,( 相当于 )-i
的参数已被弃用,但为了方便起见,我经常使用它。xargs
-I{}
输入文件:
$ tail -n+1 rep*.txt
==> rep1.txt <==
Reptile
snake
iguana
crocodile
==> rep2.txt <==
Reptile
alligator
turtle
another snake
komodo dragon
==> rep3.txt <==
Reptile
lizard
gecko
如果您需要处理格式错误的文件名,您可以考虑合并print0
并-0
选择 xargs。
答案2
多个-exec
谓词。由于-exec
仅当命令成功时才为 true,因此您不需要对第一个执行任何特殊操作grep
。
find ... -exec grep -q "Reptile" {} \; -exec grep -Hn snake {} \;
答案3
find . -type f -name "*.txt" -exec sh -c 't=$(mktemp)
for fi
do
if grep -q Reptile "$fi"
then
echo "$fi contains Reptile"
grep snake "$fi" | tee "$t"
echo "snake appeared on $(wc -l < "$t") line(s)"
fi
done
rm -f "$t"
' sh {} +
这会报告包含单词/字符串“Reptile”的文件名,即使它们不包含单词“snake”,并独立报告包含“snake”的行数。
哎呀;我误读了这个问题,并认为这是一个要求。取出来很简单:
find . -type f -exec sh -c '
for fi
do
if grep -q Reptile "$fi"
then
echo "$fi contains Reptile"
grep snake "$fi"
fi
done
' sh {} +
如果需要,您可以添加一个-n
选项。grep snake
这应该处理几乎任何有效的文件名。检查文件名以空格开头和/或包含换行符的其他答案。