usando grep -E com condições AND (ex: (? = / fo) ^ (? = / mo))

2

Não tenho muito problema em descobrir como obter uma lista de arquivos com:

  1. string "/ fo" nela
  2. Mas não tem string "/ mo"

Estou tentando descobrir isso na pasta com muitos arquivos de texto ... Minhas tentativas mal sucedidas ...

  • grep -lE '(? = / fo) ^ (? = / mo)' *
  • grep -E '(fo) (mo)' *

Estou preso aqui ... Sugestões?

    
por confiq 11.03.2013 / 11:54

1 resposta

2

Eu não acho que você pode fazer isso com um passe usando grep .

Uma solução grep de duas passagens

Esta solução usa find para passar arquivos no diretório atual para um loop while, que por sua vez faz o grep'ing desejado:

find . -maxdepth 1 -type f -print0 | while IFS= read -r -d $'
BEGINFILE { f1 = f2 = 0 }
$0 ~ pat1 { f1 = 1 }
$0 ~ pat2 { f2 = 1 }
ENDFILE   { if(f1 && !f2) print FILENAME }
' file; do grep -q '/mo' "$file" || grep -l '/fo' "$file" done

Uma solução de GNU awk de uma passagem

parse.awk

awk -f parse.awk pat1='/fo' pat2='/mo' *

Execute assim:

find . -maxdepth 1 -type f -print0 | while IFS= read -r -d $'
BEGINFILE { f1 = f2 = 0 }
$0 ~ pat1 { f1 = 1 }
$0 ~ pat2 { f2 = 1 }
ENDFILE   { if(f1 && !f2) print FILENAME }
' file; do grep -q '/mo' "$file" || grep -l '/fo' "$file" done

Explicação

O GNU awk possui o recurso BEGINFILE e ENDFILE , que são blocos executados no início e no final de um arquivo de entrada. Isso nos permite virar bandeiras quando os padrões são vistos.

O exemplo acima define os dois sinalizadores, f1 e f2 , com base em se pat1 e pat2 forem encontrados no arquivo de entrada atual. Assim, o bloco ENDFILE sabe se ambos os padrões estavam presentes no arquivo de entrada atual e pode realizar o teste apropriado.

    
por 11.03.2013 / 13:20