それぞれ深さが異なる複数のサブディレクトリがあります。特定のファイル形式(例*.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
zsh
GNUシステムから:
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: ファイル名に改行文字が含まれていない場合。