Entendo como usar a função printf do awk, mas não quero especificar todos os campos.
Por exemplo, suponha que este seja o meu arquivo:
c1|c2|c3|c4|c5
c6|c7|c8|c9|c10
c11|c12|c13|c14|c15
Quero formatá-lo para que o primeiro campo de cada registro tenha a largura de c11 - a célula mais longa no primeiro campo:
c1 |c2|c3|c4|c5
c6 |c7|c8|c9|c10
c11|c12|c13|c14|c15
Entendo que eu poderia especificar:
awk -F"|" '{printf "%-3s%s%s%s%s\n", $1, $2, $3, $4, $5}' file > newfile
Vamos supor que eu sei o que quero que a largura da primeira coluna seja, mas NÃO sei quantos campos estão no arquivo. Basicamente, quero fazer algo como:
... '{printf "%-3s|", $1}'
... e imprima o restante dos campos no formato original.
awk
text-formatting
printf
Kayli O'Keefe
fonte
fonte
sed 's/|/'' '' '' |/;s/\(...\) */\1/'
(aqui adicionar aspas extras para inserir esses 3 espaços como os comentários SE espremer espaços contíguos em um)Respostas:
Você pode usar
sprintf
para reformatar$1
apenas.Ex.
fonte
awk -vf1=3 'BEGIN{OFS=FS="|"}{$1=sprintf("%-*s",f1,$1)}1' test.txt
Para descobrir o comprimento maior / maior do primeiro campo e reformatar os valores no campo de acordo com esse comprimento, você precisará fazer duas passagens separadas sobre o arquivo.
(observe que o arquivo de entrada é especificado duas vezes na linha de comando)
Para os dados que você apresenta, isso produziria
A primeira passagem é tratada pelo
FNR == NR
bloco, que simplesmente acompanha o campo mais longo visto até agora (m
contém o comprimento máximo visto) e pula para a próxima linha.A segunda passagem é tratada pelo último bloco, que reformata o primeiro campo usando
sprintf()
. A string de formato%-*s
significa "uma string justificada à esquerda cuja largura é fornecida pelo argumento inteiro antes do argumento que contém a string real".Obviamente, isso poderia ser expandido para todas as colunas, transformando o escalar
m
em uma matriz que contém a largura máxima de cada coluna:fonte
A maneira inteligente é o que a chave de aço sugeriu . A maneira desnecessariamente complicada é iterar sobre todos os campos:
Mas apenas
sprintf
$1
e termine com isso.fonte
No Awk, você pode usar um "*" para gerar uma sequência de formato de impressão dinâmica.
Se você já conhece o comprimento, pode passar o comprimento do campo para a primeira coluna com -v.
Nota: se você não sabia qual era o tamanho da primeira coluna, poderia armazenar os valores em uma matriz, encontrando o comprimento máximo da coluna ao longo do caminho e imprimindo tudo no bloco END.
fonte