ファイルから文字列を検索し、見つかったら、ペアの名前を持つファイルが同じディレクトリにあることを確認します。

ファイルから文字列を検索し、見つかったら、ペアの名前を持つファイルが同じディレクトリにあることを確認します。

.ft1私は、特定の単語を含めることも含まない場合もある、同じエンディングを持つ多くの異なるファイルを持っていますspecial。その単語を含むファイルについて、そのディレクトリに.log異なるエンディングを持つ別のファイルがあることを確認したいと思います。

私が今まで得たものは次のとおりです。

find . -name "*.ft1" -exec grep -l "special" {} \; -execdir ls *log \;

lsただし、実行するたびにエラーが発生します。

ls: cannot access *log: No such file or directory

しかし、私は知るこのディレクトリにそのようなファイルがあります。また、アスタリスクをエスケープして式を作成しようとしましたが、-execdir ls \*log \;エラーが残っています。

私も見たことがあるこれ同様の質問ですが、現在これが私の問題を解決するのにどのように役立つのかわかりません。

どうすれば正しく動作させることができますか?.log見つかったファイルと同じ名前のファイルのみを一覧表示するソリューションのボーナスポイント.ft1

答え1

問題は、globを解釈するためにシェルが必要であることです*.log。したがって、-execdirシェルを呼び出す必要があります。次のコードスニペットは、「同じ茎」の要件も解決します。

find . -name "*.ft1" -exec grep -l "special" {} \; \
-execdir bash -c 'x=$1; x=${x%.txt}; ls "$x".log' bash {} \;

答え2

ファイル名にスペースがなく、スペースを使用する意図がないと仮定すると、find次のようになります。

for file in *.ft1; do
   if grep -q 'special' ${file}; then
      ls -l ${file%.ft1}.log 2> /dev/null
   fi
done

最終的にbash文字列操作を使用します.ft1。使用できますが、拡張子の前にある${file/ft1/log}すべてのファイル名と一致します。ft1

stderr存在しないファイルの試行を隠すようにリダイレクトしますlsls.log

答え3

使用grep -rawk

grep -rl 'special' *.ft1 | awk '{sub(/\.ft1$/,"");system("sh -c \"[ -f "$0".log ] && echo \\\"["$0".log\\\"] exists for ["$0".ft1]\"")}'

または出力ls

grep -rl 'special' *.ft1 | awk '{sub(/\.ft1$/,"");system("sh -c \"[ -f "$0".log ] && ls "$0".log \"")}'

はい

% grep -rl 'special' *.ft1 | awk '{sub(/\.ft1$/,"");system("sh -c \"[ -f "$0".log ] && echo \\\"["$0".log\\\"] exists for ["$0".ft1]\"")}'
[one.log] exists for [one.ft1]

% grep -rl 'special' *.ft1 | awk '{sub(/\.ft1$/,"");system("sh -c \"[ -f "$0".log ] && ls "$0".log \"")}'
one.log

% ls -laog                        
total 100
drwxrwx--x   4  4096 Nov 13 22:03 .
drwxr-xr-x 272 86016 Nov 13 22:03 ..
drwxrwxr-x   2  4096 Nov 13 20:37 bar
drwxrwxr-x   2  4096 Nov 13 20:37 foo
-rw-rw-r--   1     8 Nov 13 21:55 one.ft1
-rw-rw-r--   1     0 Nov 13 21:54 one.log
-rw-rw-r--   1     0 Nov 13 21:54 three.ft1
-rw-rw-r--   1     0 Nov 13 21:54 two.ft1
-rw-rw-r--   1     0 Nov 13 21:54 two.log

% cat one.ft1
special

% cat two.ft1

答え4

代替方法は次のとおりですzsh

print -rl -- **/*.ft1(.e_'grep -q special $REPLY && REPLY=$REPLY:r.log && [[ -f $REPLY ]]'_)

これにより、.ft1文字列を含むファイルが再帰的に検索され、そのファイルのみが.log印刷されます。.ft1この文字列を含むすべてのファイルを印刷したい場合special そしてその.logファイル(存在する場合)grepを.see-qに置き換えます。-l
仕組みは次のとおりです。(これは手がかりがあります -grep部分、残りは同じです)。

関連情報