GNU/Linux >> Belajar Linux >  >> Linux

Pemisah bidang default untuk awk

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 FS variabel sebagai pemisah bidang. Jika FS adalah karakter tunggal, bidang dipisahkan oleh karakter tersebut. Jika FS adalah string nol, maka setiap karakter individu menjadi bidang yang terpisah. Jika tidak, FS diharapkan menjadi ekspresi reguler penuh. Dalam kasus khusus yaitu FS adalah 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 ) - awk default di beberapa distro Linux
  • Mawk (mawk ) - awk default di beberapa Distro Linux (misalnya, versi Ubuntu sebelumnya)
  • BWK Awk - awk default pada platform mirip BSD, termasuk macOS

Versi terkini dari semua implementasi ini mengikuti standar POSIX sehubungan dengan bidang pemisah (namun bukan rekam pemisah).

Glosarium:

  • RS adalah masukan-catatan pemisah , yang menjelaskan bagaimana masukan dipecah menjadi catatan :

    • Nilai default yang dimandatkan POSIX adalah baris baru , juga disebut sebagai \n di bawah; yaitu, masukan dipecah menjadi baris secara default .
    • Aktif awk baris perintah, RS dapat ditentukan sebagai -v RS=<sep> .
    • POSIX membatasi RS menjadi 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).
  • FS adalah bidang input- pemisah , yang menjelaskan bagaimana setiap catatan dibagi menjadi bidang ; ini mungkin merupakan ekspresi reguler yang diperluas .

    • Aktif awk baris perintah, FS dapat 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.

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 RS disetel ke nilai yang menghasilkan rekaman sendiri berisi \n contoh (seperti saat RS disetel 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 \n contoh jika RS default berlaku, split() fungsi saat dipanggil tanpa argumen pemisah bidang eksplisit pada string multibaris dari sumber berbeda (mis., variabel diteruskan melalui -v pilihan atau sebagai pseudo-filename) selalu memperlakukan \n sebagai pemisah bidang.

Pertimbangan NON-default penting :

  • Menetapkan kosong string ke RS memiliki 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 dari FS berubah 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 FS ke [ ] - 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.
    • Memimpin dan mengikuti pemisah TIDAK diabaikan , dan, sebagai gantinya, pisahkan kosong bidang.
    • Menyetel FS ke string kosong artinya setiap karakter catatan adalah bidangnya sendiri .
  • Seperti yang diamanatkan oleh POSIX, jika RS disetel ke string kosong (mode paragraf), baris baru (\n ) adalah juga dianggap pemisah bidang , terlepas dari nilai FS .

  • Dengan -P berlaku dan RS setel ke string kosong , \n masih diperlakukan sebagai pemisah bidang:
    gawk -P -F' ' -v RS='' '{ printf "<%s>, <%s>\n", $1, $2 }' <<< $'a\nb'
  • Dengan -P berlaku dan tidak kosong RS , \n TIDAK 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:

  1. Spasi kosong di depan dan di belakang diabaikan selama pemisahan bidang.
  2. Kolom dipisahkan dalam rantai karakter spasi yang berdekatan yang mencakup kosong, tab, dan baris baru.
  3. 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.


Linux
  1. memeriksa pustaka bersama untuk pemuat non-default

  2. grep untuk istilah dan mengecualikan istilah lain

  3. Bagaimana cara mengatur umask default untuk servlet webdav Tomcat?

  1. Bagaimana Cara Mengatur Opsi Pemasangan Otomatis Default Untuk Media yang Dapat Dilepas?

  2. Bagaimana Cara Mengubah Panjang Baris Default Untuk Od Dan Hexdump?

  3. Backend Default yang Bagus Untuk Matplotlib?

  1. Tertangkap Dalam Lingkaran? Awk While, Do While, For Loop, Break, Continue, Exit Contoh

  2. 9 Fungsi Built-in Awk yang Kuat untuk Numerik

  3. Bagaimana cara menambahkan jalur penyertaan default untuk GCC di Linux?