すべてのサブディレクトリで、特定のファイル形式の文字列が最後に表示されることを見つけます。

すべてのサブディレクトリで、特定のファイル形式の文字列が最後に表示されることを見つけます。

それぞれ深さが異なる複数のサブディレクトリがあります。特定のファイル形式(例*.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を使用すると、ファイル名と以下の内容(2番目のgrep)を取得できます。

\[*?ファイル名にスペースや.seeが含まれていない限り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前のスペースにコピーし、緯度行はパターン$空間xにスペースを保持するように変更します。一致するとファイル名と行を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: ファイル名に改行文字が含まれていない場合。

関連情報