Awk para remover linha se o argumento for encontrado em uma coluna específica

4

Eu preciso percorrer um arquivo inteiro de tamanho desconhecido e remover qualquer linha na qual uma determinada palavra (passada como argumento 1) aparece em uma coluna especificada. Além disso, preciso acompanhar quantas linhas foram removidas. Estou assumindo que este é um trabalho para o awk, mas estou tendo muitos problemas com isso. Eu tentei trabalhar com o awk match, mas além de alguns outros problemas sintáticos, estou tendo dificuldades para traduzir o argumento em uma palavra.

Exemplo (arquivo.txt):

Katie 1234 4567 blue
Ben 3456 2345 purple
Alex 7896 6789 blue

$ script.sh blue 4

Edita o arquivo para:

Ben 3456 2345 purple

E saídas: 2 lines removed

Estou mais interessado em entender o que estou fazendo do que apenas pegar o código.

    
por Lauren 24.09.2012 / 00:41

1 resposta

5
#!/bin/sh
awk -v value="$1" -v column="$2" '
  $column == value {++removed; next}
  1 {print}
  END {print removed " lines removed" >"/dev/stderr"}
' <File.txt >File.txt.tmp &&
mv File.txt.tmp File.txt

Explicações:

  • -v value="$1" define a variável value do awk como o primeiro argumento do shell script.
  • Para cada linha, se a condição $column == value for verdadeira, o código nas chaves é executado.
    • $column é o conteúdo do número da coluna column (começando em 1).
    • ++removed incrementa um contador de linhas removidas. A variável começa em 0.
    • next pula para a próxima linha de entrada, para que a instrução print não seja executada quando a condição for verdadeira.
  • 1 {print} imprime todas as linhas que não fizeram com que a diretiva next fosse executada. ( 1 é uma condição sempre verdadeira).
  • END {…} executa o código dentro das chaves no final da entrada.
  • O código awk grava em um arquivo temporário que é movido para o lugar.
por 24.09.2012 / 01:37