查找所有子目录中给定文件类型中字符串的最后一次出现

查找所有子目录中给定文件类型中字符串的最后一次出现

我有多个子目录,每个子目录的深度都不同。我需要在特定文件类型(例如*.out)中搜索字符串的最后一次出现。我该如何实现?

我努力了:

grep -r 'string' **/*.out | tail -1

但这只给了我最后一个文件的最后一个字符串。

答案1

假设您位于子目录的父目录中:

find . -type f -name '*.out' -exec sh -c '
  for f do
    grep "string" /dev/null "$f" | tail -n 1
  done
' sh {} +

答案2

我会使用类似的东西:

for i in `find . -name "*.out" -type f`;
do
grep -l 'string' $i
grep 'string' $i|tail -1
done

使用第一个 grep,您将获得文件名和下面(第二个 grep)的内容。

只要文件名不包含空格或\[*?.看cuonglm 的回答以获得强大的解决方案。

答案3

zshGNU 系统上:

for f (**/*.out(.)) tac < $f | grep --label=$f -m1 string

答案4

使用gnu工具,您可以使用一次调用gawk

awk '/pattern/{l=$0} ENDFILE{if (l) {print FILENAME ":" l; l=""}}' **/*.out

(如果行匹配,则将其存储到l每个文件末尾的 ; 中,如果l不为空,则打印文件名,l然后重置l

或者sed

sed -ns '/pattern/h;${x;//{F;p}}' **/*.out

(如果行匹配,复制到h旧空间;如果 la $t 行,ex更改保持空间 w.模式空间;如果匹配,则p打印F文件名和行)
尽管输出不同 - 文件名和相应的最后一个匹配行位于不同的位置线 - 但如果通过管道传输到另一个sed例如

sed -ns '/pattern/h;${x;//{F;p}}' **/*.out |sed '$!N;s/\n/:/'

它将模拟grep输出1
上述假设巴什(第 4 节带shopt -s globstar) 或桀骜。要包含隐藏文件,请添加shopt -s dotglob(巴什) 或者setopt dotglob桀骜)。


1:只要这些文件名都不包含换行符。

相关内容