A exclusão de campos no awk é notoriamente difícil. Parece ser uma operação tão simples (e geralmente necessária), mas é mais difícil do que deveria.
Veja Existe uma maneira de excluir completamente os campos no awk, para que os delimitadores extras não sejam impressos? do Stack Overflow para uma boa maneira de fazer isso.
Eu copiei a função rmcol()
na resposta do @ ghoti, para que tenhamos uma cópia aqui no U & L:
function rmcol(col, i) {
for (i=col; i<NF; i++) {
$i=$(i+1)
}
NF--
}
Exclui a coluna especificada da linha de entrada atual e diminui o contador de campo ( NF
) para corresponder.
Não faço ideia do que a sua função transform()
faz, por isso nem vou tentar duplicar isso - mas aqui está um exemplo de usar rmcol()
em awk
one-liner:
$ echo 'field1,field2,field3' | awk -F, -v OFS=, '
function rmcol(col, i) {
for (i=col; i<NF; i++) {
$i=$(i+1)
}
NF--
}
{ rmcol(2); print; }
'
field1,field3
BTW, se você precisar excluir vários campos de uma linha de entrada, é melhor / mais fácil excluí-los na ordem inversa. Ou seja, exclua os campos com numeração mais alta primeiro . Por quê? Porque os campos com numeração mais alta serão renumerados toda vez que você excluir um campo com numeração mais baixa, dificultando muito o controle de qual número de campo pertence a qual campo.
BTW, delete()
in awk
é para excluir elementos de uma matriz - não para excluir campos de uma linha de entrada. Você poderia split()
de cada linha de entrada (em FS
) em uma matriz e excluir o 2º elemento da matriz, mas teria que gravar uma função join()
para imprimir a matriz com uma vírgula (ou OFS
) separando cada campo.
Mesmo isso seria mais complicado do que seria de se esperar, porque todos os arrays em awk
são matrizes associativas (ou seja, não numericamente indexados) - então delete(array[2])
won ' t muda automaticamente os elementos da matriz 3+ para os elementos 2+. Você teria que escrever sua própria função de wrapper em torno de delete()
para fazer praticamente a mesma coisa para arrays que rmcol()
faz para campos de entrada.