web-dev-qa-db-ja.com

ある文字列を含み、他の文字列を含まないファイルを検索する

たくさんの.txtファイルがあるフォルダにいます。stringAは含まれているがstringBは含まれていないすべてのファイルを検索したいと思います(これらは必ずしも同じではありません)ライン)。誰でもこれを行う方法を知っていますか?

33
SoftTimur

ファイル名にスペース、タブ、改行、またはワイルドカード文字が含まれていない限り、grepが_-L_オプションをサポートしている場合は、次のように実行できます。

_$ cat file1
stringA
stringC
$ cat file2
stringA
stringB
$ grep -L stringB $(grep -l stringA file?)
file1
_

サブシェル$()で実行されるgrepは、stringAを含むすべてのファイル名を出力します。このファイルリストは、grepを含まないすべてのファイルをリストするメインのstringBコマンドの入力です。

_man grep_から

_  -v, --invert-match
          Invert the sense of matching, to select non-matching lines.  (-v is specified by POSIX.)

  -L, --files-without-match
          Suppress normal output; instead print the name of each input file from which no output would normally have been printed.  The scanning will stop on the first match.

  -l, --files-with-matches
          Suppress normal output; instead print the name of each input file from which output would normally have been printed.  The scanning will stop on the first match.  (-l is specified by POSIX.)
_
35
Bernhard

GNUツール:

grep -lZ stringA ./*.txt |
  xargs -r0 grep -L stringB

-L-Z-r-0はGNU拡張機能ですが、他の一部の実装では必ずしもそうではありません。

4
#run loop for each file in the directory
for i in `ls -l | tail -n+2 | awk '{print $NF}'` ; do
   #check if file contains "string B" 
   #if true then filename is not printed
   if [[ `egrep "string B" $i | wc -l` -eq 0 ]] ; then
      #check if file contains "string A"
      #if false then file name is not printed
      if [[ `egrep "string A" $i | wc -l` -gt 0 ]] ; then
         #file name is printed only if "string A" is present and "string B" is absent
         echo $i
      fi
   fi
done

ベルンハルトの答えを確認した後:

grep -Le "string B" $(grep -le "string A" `ls`)

ファイル名にスペースが含まれている場合:

grep -L stringB $(grep -l stringA `ls -l | tail -n+2 | awk '{print $NF}' | sed -e 's/\s/\\ /g'`
0
debal