Função de invólucro do awk simples ou alias

3

Eu vi alguém usar um alias bash ou função baseada no awk, o que eu gostei por sua simplicidade, mas não consigo me lembrar de como implementá-lo (no bash).

Digamos que você tenha um arquivo formatado grande, do qual você precisa escolher digamos 3, 4, 7a coluna.

Para isso, você pode fazer:

cat bigfile.txt | awk '{print $3, $4, $7}' |less

Eu preciso de um alias (ou função) pawk, que eu possa usar como:

cat bigfile.txt | pawk 3,4,7 | less

para obter o mesmo efeito. O número de colunas pode ser arbitrário e pode incluir NF. Eu tentei algumas coisas para implementar isso, mas não consigo descobrir como passar um número arbitrário de variáveis para o awk.

    
por Tarundeep Singh 11.05.2016 / 16:17

2 respostas

2

Você pode usar uma função assim:

function pawk(){
  awkString="{print "

  for var in "$@"
  do
    awkString+=" \$$var"
  done

  awkString+=" }"

  awk "$awkString"
}

Exemplo:

cat bigfile.txt | pawk 3 4 7 | less
    
por 11.05.2016 / 16:33
2

Sim, isso provavelmente teria sido uma função, não um alias. Com isso em mente, tente isto:

pawk(){
    fields="$(sed -E 's/(^|,)/ \$/g'<<<"$1")"
    shift
    awk "{print $fields}" "$@"
}

Então você pode executá-lo como:

pawk 3,4,7 bigfile.txt | less

Ou

cat bigfile | pawk 3,4,7 | less

Ou até mesmo

pawk 3,4,7 * | less

O truque é adicionar um $ antes de cada vírgula e no início do primeiro argumento dado à função (assim 1,2,3 se torna $1,$2,$3 ) e salvar a string resultante em uma variável shell. Em seguida, você executa awk entre aspas duplas para que a variável $fields seja expandida e awk a trate como os firewalls que ela deve imprimir.

O sed -E deve ser bastante portátil, mas o herestring ( <<<"$1" ) menos. Para uma versão totalmente portátil, use isto:

pawk(){
    fields="$(printf '$%s' $(echo 1,2,3 | sed 's/,/,\$/g'))"
    shift
    awk "{print $fields}" "$@"
}
    
por 11.05.2016 / 16:51

Tags