Encontre arquivos contendo uma string, mas não a outra [duplicata]

22

Eu estou em uma pasta com muitos arquivos .txt , gostaria de encontrar todos os arquivos que contêm stringA , mas não contêm stringB (eles não estão necessariamente na mesma linha). Alguém sabe como fazer isso?

    
por SoftTimur 08.05.2014 / 08:40

3 respostas

22

Contanto que seus nomes de arquivos não contenham espaços, tabulações, novas linhas ou caracteres curinga, e se o seu grep suportar a opção -L , você poderá fazer da seguinte maneira:

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

O grep executado na subshell $() imprimirá todos os nomes de arquivos que contiverem stringA . Esta lista de arquivos é entrada para o comando principal grep , que lista todos os arquivos que não contêm stringB .

De 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.)
    
por 08.05.2014 / 08:44
3

Com ferramentas GNU:

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

-L , -Z , -r , -0 são extensões do GNU às vezes, mas nem sempre encontradas em outras implementações.

    
por 05.06.2014 / 17:41
0
#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

Após verificar a resposta de Bernhard:

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

Se o nome do arquivo contiver espaços:

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

Tags