Suprimir linhas com awk

1

Eu tenho uma variável de bash com várias linhas: $WORDS contendo uma palavra em cada linha.
Eu tenho outra variável de bash de várias linhas: $LIST também contém uma palavra em cada linha.

Eu quero limpar $LIST de qualquer palavra presente em $WORDS .

Atualmente faço isso com while read e grep , mas isso não é sexy.

WORDS=$(echo -e 'cat\ntree\nearth\nred')
LIST=$(echo -e 'abcd\n1234\nred\nwater\npage\ncat')
while read -r LINE; do
    LIST=$(echo "$LIST" | grep -v "$LINE")
done <<< "$WORDS"
echo "$LIST"

Acho que posso fazer isso com awk , mas não consegui fazer isso funcionar.
Alguém pode me explicar como fazer isso com o awk?

    
por Gregory MOUSSAT 09.06.2017 / 01:18

2 respostas

3

Isso deve cumprir o que você está tentando fazer.

WORDS=$(echo -e 'cat\ntree\nearth\nred')
LIST=$(echo -e 'abcd\n1234\nred\nwater\npage\ncat')

echo "$LIST" | awk -v WORDS="$WORDS" '
BEGIN {
  split(WORDS,w1,"\n")
  for (w in w1) { w2[w1[w]] = 1 }
}
{
  if (w2[$0] != 1) { print $0 }
}'

Veja como funciona. Primeiro, estou usando a opção -v na linha de comando do awk para passar a lista de palavras como uma variável. Esta variável será visível dentro do programa awk com o nome WORDS.

O bloco BEGIN é executado antes que qualquer entrada seja processada. Ele contém duas linhas

split(WORDS,w1,"\n")

Este comando split usa a lista de palavras e o transforma em um array chamado w1.

for (w in w1) { w2[w1[w]] = 1 }

Esse loop percorre a matriz w1 e gera uma matriz associativa chamada w2. Converter o array em um array associativo melhorará o desempenho.

Em seguida, temos o corpo principal do loop que processa a lista.

if (w2[$0] != 1) { print $0 }

Isto irá verificar cada linha de entrada em relação ao nosso array associativo e somente imprimirá a linha se a palavra não foi encontrada. Como atribuímos cada chave a 1 em nosso bloco BEGIN, precisamos verificar apenas se o valor dessa chave é igual a 1 para saber se ela está definida.

    
por 09.06.2017 / 06:32
2

Sugiro

echo "$LIST" | grep -vf <(echo "$WORDS")
    
por 09.06.2017 / 12:13

Tags