Tenho o seguinte para imprimir uma linha tracejada com base na linha mais longa de um arquivo csv:
awk -F ',' '
BEGIN {
longest_line=0
for (i = 1; i <= NF; i++) {
longest[i] = ""
}
}
{
for (i = 1; i <= NF; i++) {
if (length($i) > length(longest[i])) {
longest[i] = $i
}
}
}
END {
for (i=1; i<=NF;i++) {
longest_line += length(longest[i])
}
printf("%*s", longest_line, "=")
}
'
Aqui está o script completo:
awk -F ',' -v smso="$smso" -v rmso="$rmso" 'BEGIN {
count=1
firstcol=0
arraylen=1
longest_line=0
for (i = 1; i <= NF; i++) {
longest[i] = ""
}
}
{
for (i=1;i<=NF;i++) {
if (i==NF) {
data[arraylen++]=$i
data[arraylen++]="\n"
} else {
data[arraylen++]=$i
}
}
}
{
for (i = 1; i <= NF; i++) {
if (length($i) > length(longest[i])) {
longest[i] = $i
}
}
}
END {
for (i=1; i<=NF;i++) {
longest_line += length(longest[i])
}
printf("%*s", longest_line, "b")
for (i = 1; i <= length(data); i++) {
if (data[i]=="\n") {
firstcol++
count=1
printf("%s", data[i])
} else if (count==1 && i != 1) {
printf("%s%s%s", "|", data[i], "|")
count++
} else {
smso=$(tput smso)
rmso=$(tput rmso)
num_spaces=(length(longest[count])-length(data[i]))+1
printf("%s%*s%s%s", (i==1?"|":""), (i==1?num_spaces-1:num_spaces), " ", firstcol==0?toupper(data[i]):data[i], "|")
count++
}
}
}'
arquivo de entrada é:
NUMBER,FNAME,LNAME,PHONE-TYPE:GROUPS
222-222-2222,Elizabeth,Taylor,office:beauty:
111-111-1111,Matt,Alex,personal:superhuman:cool:amazing:extra
e a saída desejada é:
==============================================================
| NUMBER| FNAME| LNAME| PHONE-TYPE:GROUPS|
|222-222-2222| Elizabeth| Taylor| office:beauty:|
|111-111-1111| Matt| Alex| personal:cool:amazing:extra|
mas minha saída é:
=
| NUMBER| FNAME| LNAME| PHONE-TYPE:GROUPS|
|222-222-2222| Elizabeth| Taylor| office:beauty:|
|111-111-1111| Matt| Alex| personal:cool:amazing:extra|
sprintf("%*s", n, string)
preenche a string à esquerda com um comprimento (em número de bytes ou caracteres, dependendo daawk
implementação) den
com espaços .Para repetir uma string n vezes, você poderia escrever uma função auxiliar:
Aqui, sugiro usar
mlr
o que faz isso (ou algo semelhante) pronto para uso (e processa CSVs corretamente):Ou para campos alinhados à direita:
Se
mlr
não estiver disponível, em vez deawk
, eu usariaperl
o que foi amplamente substituídoawk
.Que dá:
Com os cabeçalhos em negrito e azul.
Em
perl
, a repetição de strings é feita com ox
operador de repetição:"string" x 3
resulta emstringstringstring
. Vejaperldoc perlop
para detalhes.Embora
perl
você raramente precise reinventar a roda como nos 35 anos de existência, os módulos perl foram escritos para praticamente qualquer coisa. Já usamos oList::Util
módulo com algumas funções úteis de manipulação de lista eTerm::ANSIColor
para gerar texto colorido acima, mas há também umText::CSV
módulo para processar CSVs eText::ASCIITable
formatar tabelas:imprime um
=
caractere recuado porlongest_line-1
espaços em branco. Você quer isso em vez disso:FWIW, é assim que eu escreveria o código para fazer o que você parece estar tentando fazer, usando qualquer awk:
Preencha alguns campos com espaços conforme achar adequado, alterando
val = $colNr
paraval = " " $colNr " "
ou similar.