Suchen Sie nach Dateien, die eine Zeichenfolge enthalten, die andere jedoch nicht

Suchen Sie nach Dateien, die eine Zeichenfolge enthalten, die andere jedoch nicht

Ich befinde mich in einem Ordner mit vielen .txtDateien und möchte alle Dateien finden, die Folgendes enthalten stringA, aber nicht enthalten stringB(sie stehen nicht unbedingt in derselben Zeile). Weiß jemand, wie das geht?

Antwort1

Sofern Ihre Dateinamen keine Leerzeichen, Tabulatoren, Zeilenumbrüche (ein unverändertes $IFS) oder Platzhalterzeichen enthalten und nicht mit beginnen -, und Ihr Server grepdiese Option unterstützt -L, können Sie wie folgt vorgehen:

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

Das grepin der Subshell ausgeführte $(), gibt alle Dateinamen aus, die enthalten stringA. Diese Dateiliste ist die Eingabe für den Hauptbefehl grep, der alle Dateien auflistet, die nicht enthalten stringB.

Ausman 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.)

Antwort2

Mit GNU-Tools:

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

-L, -Z, -r, -0sind manchmal GNU-Erweiterungen, sind aber nicht immer in anderen Implementierungen zu finden.

Antwort3

#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

Nach Überprüfung von Bernhards Antwort:

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

Wenn der Dateiname Leerzeichen enthält:

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

verwandte Informationen