Mari kita lihat halaman manual awk GNU:
FS— Pemisah kolom input, spasi secara default. Lihat Bidang , di atas.
Ke Bidang bagian!
Saat setiap catatan masukan dibaca, gawk membagi catatan menjadi beberapa bidang, menggunakan nilai
FSvariabel sebagai pemisah bidang. JikaFSadalah karakter tunggal, bidang dipisahkan oleh karakter tersebut. JikaFSadalah string nol, maka setiap karakter individu menjadi bidang yang terpisah. Jika tidak,FSdiharapkan menjadi ekspresi reguler penuh. Dalam kasus khusus yaituFSadalah satu spasi, kolom dipisahkan oleh rangkaian spasi dan/atau tab dan/atau baris baru.
Inilah ringkasan pragmatis yang berlaku untuk semua penerapan Awk utama :
- GNU Awk (
gawk) -awkdefault di beberapa distro Linux - Mawk (
mawk) -awkdefault di beberapa Distro Linux (misalnya, versi Ubuntu sebelumnya) - BWK Awk -
awkdefault pada platform mirip BSD, termasuk macOS
Versi terkini dari semua implementasi ini mengikuti standar POSIX sehubungan dengan bidang pemisah (namun bukan rekam pemisah).
Glosarium:
-
RSadalah masukan-catatan pemisah , yang menjelaskan bagaimana masukan dipecah menjadi catatan :- Nilai default yang dimandatkan POSIX adalah baris baru , juga disebut sebagai
\ndi bawah; yaitu, masukan dipecah menjadi baris secara default . - Aktif
awkbaris perintah,RSdapat ditentukan sebagai-v RS=<sep>. - POSIX membatasi
RSmenjadi harfiah, karakter tunggal nilai, tetapi GNU Awk dan Mawk mendukung multi-karakter nilai yang mungkin merupakan ekspresi reguler yang diperluas (BWK Awk tidak dukung itu).
- Nilai default yang dimandatkan POSIX adalah baris baru , juga disebut sebagai
-
FSadalah bidang input- pemisah , yang menjelaskan bagaimana setiap catatan dibagi menjadi bidang ; ini mungkin merupakan ekspresi reguler yang diperluas .- Aktif
awkbaris perintah,FSdapat ditentukan sebagai-F <sep>(atau-v FS=<sep>). - Nilai default yang dimandatkan POSIX adalah secara formal sebuah ruang (
0x20), tetapi ruang itu tidak secara harfiah diartikan sebagai (satu-satunya) pemisah, tetapi memiliki makna khusus ; lihat di bawah.
- Aktif
Secara default :
- lari apapun dari spasi dan/atau tab dan/atau baris baru diperlakukan sebagai pemisah kolom
- dengan perjalanan di depan dan di belakang diabaikan .
Perhatikan bahwa dengan pemisah rekaman masukan default (RS ), \n , baris baru biasanya jangan masukkan gambar sebagai pemisah bidang , karena tidak ada catatan itu sendiri berisi \n dalam hal itu.
Baris baru sebagai pemisah bidang lakukan ikut bermain , namun:
- Kapan
RSdisetel ke nilai yang menghasilkan rekaman sendiri berisi\ncontoh (seperti saatRSdisetel ke string kosong; lihat di bawah). - Umumnya , ketika
split()fungsi digunakan untuk membagi string menjadi elemen larik tanpa argumen pemisah bidang eksplisit.- Meskipun masukan mencatat tidak akan berisi
\ncontoh jikaRSdefault berlaku,split()fungsi saat dipanggil tanpa argumen pemisah bidang eksplisit pada string multibaris dari sumber berbeda (mis., variabel diteruskan melalui-vpilihan atau sebagai pseudo-filename) selalu memperlakukan\nsebagai pemisah bidang.
- Meskipun masukan mencatat tidak akan berisi
Pertimbangan NON-default penting :
-
Menetapkan kosong string ke
RSmemiliki arti khusus :membaca input dalam mode paragraf , artinya input dipecah menjadi catatan oleh berjalannya baris tidak kosong , dengan garis kosong di depan dan di belakang diabaikan . -
Saat Anda menetapkan sesuatu lainnya daripada literal spasi ke
FS, interpretasi dariFSberubah secara fundamental :- Sebuah tunggal karakter atau setiap karakter dari karakter tertentu set diakui secara individual sebagai pemisah bidang - bukan berjalan itu, seperti dengan default.
- Misalnya, menyetel
FSke[ ]- meskipun itu efektif berjumlah satu spasi - menyebabkan setiap individu instance space di setiap catatan untuk diperlakukan sebagai pemisah bidang. - Untuk mengenali berjalan , bilangan regex (simbol duplikasi)
+harus digunakan; mis.,[\t]+akan mengenali berjalan tab sebagai pemisah tunggal.
- Misalnya, menyetel
- Memimpin dan mengikuti pemisah TIDAK diabaikan , dan, sebagai gantinya, pisahkan kosong bidang.
- Menyetel
FSke string kosong artinya setiap karakter catatan adalah bidangnya sendiri .
- Sebuah tunggal karakter atau setiap karakter dari karakter tertentu set diakui secara individual sebagai pemisah bidang - bukan berjalan itu, seperti dengan default.
-
Seperti yang diamanatkan oleh POSIX, jika
RSdisetel ke string kosong (mode paragraf), baris baru (\n) adalah juga dianggap pemisah bidang , terlepas dari nilaiFS.
- Dengan
-Pberlaku danRSsetel ke string kosong ,\nmasih diperlakukan sebagai pemisah bidang:
gawk -P -F' ' -v RS='' '{ printf "<%s>, <%s>\n", $1, $2 }' <<< $'a\nb' - Dengan
-Pberlaku dan tidak kosongRS,\nTIDAK diperlakukan sebagai pemisah bidang - ini adalah perilaku usang:
gawk -P -F' ' -v RS='|' '{ printf "<%s>, <%s>\n", $1, $2 }' <<< $'a\nb'
Perbaikan akan datang , menurut pengelola GNU Awk; mengharapkannya dalam versi 4.2 (tidak ada kerangka waktu yang diberikan).
(Ujung topi untuk @JohnKugelman dan @EdMorton atas bantuan mereka.)
'[ ]+' berfungsi untuk saya. Jalankan awk -W version untuk mendapatkan versi awk. Milik saya adalah GNU Awk 4.0.2 .
# cat a.txt
tcp 0 0 10.192.25.199:65002 0.0.0.0:* LISTEN
tcp 0 0 127.0.0.1:26895 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:111 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:18422 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN
tcp 0 0 10.192.25.199:8888 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:50010 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:50075 0.0.0.0:* LISTEN
tcp 0 0 10.192.25.199:8093 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:8670 0.0.0.0:* LISTEN
Misalnya, saya ingin mendapatkan port Listen. Jadi saya perlu menggunakan pembatas default awk yang ditambahkan dengan ':'
# cat a.txt | awk -F '[ ]+|:' '{print $5}'
65002
26895
111
18422
22
8888
50010
50075
8093
8670
Jika Anda hanya ingin menguji pembatas default, Anda dapat menjalankan
# cat a.txt | awk -F '[ ]+' '{print $4}'
10.192.25.199:65002
127.0.0.1:26895
0.0.0.0:111
0.0.0.0:18422
0.0.0.0:22
10.192.25.199:8888
0.0.0.0:50010
0.0.0.0:50075
10.192.25.199:8093
0.0.0.0:8670
Hasilnya seperti yang diharapkan.
Pertanyaan the default delimiter is only space for awk? ambigu tetapi saya akan mencoba menjawab kedua pertanyaan yang mungkin Anda tanyakan.
Nilai default dari FS variabel (yang menampung pemisah bidang yang memberi tahu awk cara memisahkan catatan ke dalam bidang saat dibaca) adalah karakter spasi tunggal.
Hal yang awk gunakan untuk memisahkan catatan ke dalam bidang adalah "pemisah bidang" yang merupakan ekspresi reguler dengan beberapa fungsi tambahan yang hanya berlaku jika pemisah bidang adalah satu karakter kosong. Fungsionalitas tambahan itu adalah:
- Spasi kosong di depan dan di belakang diabaikan selama pemisahan bidang.
- Kolom dipisahkan dalam rantai karakter spasi yang berdekatan yang mencakup kosong, tab, dan baris baru.
- Jika Anda ingin menggunakan karakter kosong literal sebagai pemisah bidang, Anda harus menentukannya sebagai
[ ]alih-alih hanya char kosong literal mandiri seperti yang Anda bisa di regexp.
Selain pemisah bidang yang digunakan untuk membagi catatan menjadi bidang saat input dibaca, mereka digunakan dalam beberapa konteks lain, mis. arg ke-3 untuk split() , jadi penting bagi Anda untuk mengetahui konteks mana yang memerlukan string atau regexp atau fieldsep dan halaman manual dengan jelas menentukan masing-masing.
Antara lain, hal di atas menjelaskan hal ini:
$ echo ' a b c ' | awk '{printf "%d: <%s> <%s> <%s>\n", NF, $1, $2, $3}'
3: <a> <b> <c>
$ echo ' a b c ' | awk -F' ' '{printf "%d: <%s> <%s> <%s>\n", NF, $1, $2, $3}'
3: <a> <b> <c>
$ echo ' a b c ' | awk -F'[ ]' '{printf "%d: <%s> <%s> <%s>\n", NF, $1, $2, $3}'
5: <> <a> <b>
jadi jika Anda tidak mengerti mengapa 2 yang pertama menghasilkan keluaran yang sama tetapi yang terakhir berbeda, tanyakan.