Saya mengerti cara menggunakan fungsi printf awk, tetapi saya tidak ingin menentukan setiap bidang.
Misalnya, anggap ini file saya:
c1|c2|c3|c4|c5
c6|c7|c8|c9|c10
c11|c12|c13|c14|c15
Saya ingin memformatnya sehingga bidang pertama setiap rekaman adalah lebar c11 - sel terpanjang di bidang pertama:
c1 |c2|c3|c4|c5
c6 |c7|c8|c9|c10
c11|c12|c13|c14|c15
Saya mengerti bahwa saya dapat menentukan:
awk -F"|" '{printf "%-3s%s%s%s%s\n", $1, $2, $3, $4, $5}' file > newfile
Anggap saja saya tahu lebar kolom pertama yang saya inginkan, tetapi saya TIDAK tahu berapa banyak bidang dalam file. Pada dasarnya saya ingin melakukan sesuatu seperti:
... '{printf "%-3s|", $1}'
... dan kemudian cetak bidang lainnya dalam format aslinya.
awk
text-formatting
printf
Kayli O'Keefe
sumber
sumber
sed 's/|/'' '' '' |/;s/\(...\) */\1/'
(di sini menambahkan tanda kutip tambahan untuk menyisipkan 3 ruang tersebut ketika komentar SE memeras ruang yang berdekatan menjadi satu)Jawaban:
Anda dapat menggunakan
sprintf
untuk memformat ulang$1
saja.Ex.
sumber
awk -vf1=3 'BEGIN{OFS=FS="|"}{$1=sprintf("%-*s",f1,$1)}1' test.txt
Untuk mengetahui panjang terbesar / terpanjang dari bidang pertama, dan kemudian memformat ulang nilai di bidang sesuai dengan panjang itu, Anda harus melakukan dua lintasan terpisah atas file.
(perhatikan bahwa file input ditentukan dua kali pada baris perintah)
Untuk data yang Anda sajikan, ini akan menghasilkan
Lulus pertama ditangani oleh
FNR == NR
blok, yang hanya melacak bidang terpanjang yang terlihat sejauh ini (m
berisi panjang maksimum yang terlihat), dan melompat ke baris berikutnya.Lulus kedua ditangani oleh blok terakhir, yang memformat ulang bidang pertama yang digunakan
sprintf()
. String format%-*s
berarti "string yang dibenarkan kiri yang lebarnya diberikan oleh argumen integer sebelum argumen yang menyimpan string sebenarnya".Ini jelas dapat diperluas untuk melakukan semua kolom dengan mengubah skalar
m
menjadi array yang memiliki lebar maksimum setiap kolom:sumber
Cara cerdas adalah apa yang disarankan steeldriver . Cara berbelit-belit yang tidak perlu adalah beralih ke setiap bidang:
Tapi adil
sprintf
$1
dan selesai dengan itu.sumber
Di Awk Anda dapat menggunakan "*" untuk menghasilkan string format printf dinamis.
Jika Anda sudah tahu panjangnya, Anda bisa melewati panjang bidang untuk kolom pertama dengan -v.
Catatan: jika Anda tidak tahu berapa panjang kolom pertama Anda, Anda bisa menyimpan nilai-nilai dalam array kemudian menemukan panjang max col sepanjang jalan dan mencetak semuanya di blok END.
sumber