Rozumiem, jak korzystać z funkcji printf awk, ale nie chcę określać wszystkich pól.
Załóżmy na przykład, że to mój plik:
c1|c2|c3|c4|c5
c6|c7|c8|c9|c10
c11|c12|c13|c14|c15
Chcę go sformatować tak, aby pierwszym polem każdego rekordu była szerokość c11 - najdłuższa komórka w pierwszym polu:
c1 |c2|c3|c4|c5
c6 |c7|c8|c9|c10
c11|c12|c13|c14|c15
Rozumiem, że mógłbym określić:
awk -F"|" '{printf "%-3s%s%s%s%s\n", $1, $2, $3, $4, $5}' file > newfile
Załóżmy, że wiem, jaka powinna być szerokość pierwszej kolumny, ale NIE wiem, ile pól jest w pliku. Zasadniczo chcę zrobić coś takiego:
... '{printf "%-3s|", $1}'
... a następnie wydrukuj pozostałe pola w oryginalnym formacie.
awk
text-formatting
printf
Kayli O'Keefe
źródło
źródło
sed 's/|/'' '' '' |/;s/\(...\) */\1/'
(tutaj dodając dodatkowe cytaty w celu wstawienia tych 3 spacji, gdy komentarze SE ściskają ciągłe spacje w jednym)Odpowiedzi:
Możesz użyć tylko
sprintf
do ponownego sformatowania$1
.Dawny.
źródło
awk -vf1=3 'BEGIN{OFS=FS="|"}{$1=sprintf("%-*s",f1,$1)}1' test.txt
Aby obliczyć największą / najdłuższą długość pierwszego pola, a następnie sformatować wartości w polu zgodnie z tą długością, należy wykonać dwa osobne przejścia nad plikiem.
(zwróć uwagę, że plik wejściowy jest określony dwukrotnie w wierszu poleceń)
W przypadku danych, które przedstawisz, wygeneruje to
Pierwsze przejście jest obsługiwane przez
FNR == NR
blok, który po prostu śledzi najdłuższe widoczne pole (m
zawiera maksymalną widoczną długość) i przeskakuje do następnej linii.Drugie przejście jest obsługiwane przez ostatni blok, który ponownie formatuje pierwsze pole za pomocą
sprintf()
. Łańcuch formatu%-*s
oznacza „ ciąg wyrównany do lewej, którego szerokość jest podawana przez argument liczby całkowitej przed argumentem zawierającym rzeczywisty ciąg”.Można to oczywiście rozszerzyć na wszystkie kolumny, zmieniając skalar
m
w tablicę, która przechowuje maksymalną szerokość każdej kolumny:źródło
Inteligentny sposób sugeruje Steeldriver . Niepotrzebnie zawiłym sposobem jest iteracja po każdej dziedzinie:
Ale słusznie
sprintf
$1
i skończ z tym.źródło
W Awk możesz użyć „*”, aby wygenerować ciąg formatu dynamicznego printf.
Jeśli znasz już długość, możesz podać długość pola dla pierwszej kolumny za pomocą opcji -v.
Uwaga: jeśli nie wiesz, jaka jest długość pierwszej kolumny, możesz zapisać wartości w tablicy, a następnie znaleźć maksymalną długość kolumny po drodze i wydrukować ją w bloku END.
źródło