Bagaimana cara menggunakan ":" sebagai pemisah bidang awk?


243

Diberikan perintah berikut:

echo "1: " | awk '/1/ -F ":" {print $1}'

mengapa output awk:

1: 

Jawaban:


382

"-F" adalah argumen baris perintah yang bukan awk sintaks, coba:

 echo "1: " | awk -F  ":" '/1/ {print $1}'

42
Pertanyaan bodoh di sini: bagian / 1 adalah untuk mengatakan awk hanya memproses baris (atau catatan lebih tepatnya) yang berisi angka 1 kan?
rantsh

3
Sintaks @rantsh Awk sepertinya (pattern){action}. Jika pattern(kebanyakan pernyataan bersyarat) benar , actiondieksekusi. Jika patterntidak tersedia, truetersirat. Di sini patternadalah /1/negara yang 1dicocokkan regex dalam catatan saat ini$0
kvantour

62

Jika Anda ingin melakukannya secara terprogram, Anda dapat menggunakan FSvariabel:

echo "1: " | awk 'BEGIN { FS=":" } /1/ { print $1 }'

Perhatikan bahwa jika Anda mengubahnya di loop utama daripada BEGIN loop, itu akan mempengaruhi baris berikutnya yang dibaca, karena baris saat ini telah terpecah.


35

Anda memiliki banyak cara untuk ditetapkan :sebagai pemisah:

awk -F: '{print $1}'

awk -v FS=: '{print $1}'

awk '{print $1}' FS=:

awk 'BEGIN{FS=":"} {print $1}'

Semuanya setara dan untuk akan kembali 1untuk input sampel "1: 2: 3":

$ awk -F: '{print $1}' <<< "1:2:3"
1
$ awk -v FS=: '{print $1}' <<< "1:2:3"
1
$ awk '{print $1}' FS=: <<< "1:2:3"
1
$ awk 'BEGIN{FS=":"} {print $1}' <<< "1:2:3"
1

mana cara yang disukai? saya berasumsi contoh terakhir dengan BEGINpernyataan akan menjadi yang paling benar (konsisten dengan awksintaksis keseluruhan ).

1
@randomware semuanya baik-baik saja. Saya cenderung menggunakan BEGINjika saya menggunakan file untuk menyimpan semuanya, sementara -Fberguna dengan satu-liner.
fedorqui 'SO berhenti merugikan'

1
Harus dikatakan bahwa ada perbedaan halus antara kasus ketiga dan yang lainnya. Contoh: awk 'BEGIN{print split("foo:bar",a)}' FS=":" filedanawk 'BEGIN{FS=":"; print split("foo:bar",a)}' file
kvantour


12

-Fadalah argumen untuk awkdirinya sendiri:

$echo "1: " | awk -F":" '/1/ {print $1}'
1

2
Tidak perlu mengutip titik dua.
ceving

6

Anda juga dapat menggunakan regex sebagai pemisah bidang, yang berikut ini akan mencetak "bar" dengan menggunakan regex untuk menetapkan angka "10" sebagai pemisah.

echo "foo 10 bar" | awk -F'[0-9][0-9]' '{print $2}'

4

Tidak Perlu banyak menulis ini. Masukkan saja pemisah bidang yang Anda inginkan dengan opsi -F di perintah awk dan nomor kolom yang ingin Anda cetak dipisahkan sesuai pemisah bidang yang Anda sebutkan.

echo "1: " | awk -F: '{print $1}'    
1

echo "1#2" | awk -F# '{print $1}'  
1

4

AWK berfungsi sebagai penerjemah teks yang berlaku secara linier untuk seluruh dokumen dan berlaku secara fieldwise untuk setiap baris sehingga $ 1, $ 2 .. $ n adalah referensi ke bidang masing-masing baris ($ 1 adalah bidang pertama, $ 2 adalah bidang kedua dan seterusnya ...). Anda dapat mendefinisikan pemisah bidang dengan menggunakan sakelar "-F" di bawah baris perintah atau dalam dua tanda kurung dengan "FS = ...". Sekarang pertimbangkan jawaban "JUERGEN":

echo "1: " | awk -F  ":" '/1/ {print $1}'

Di atas batas bidang ditetapkan oleh ":" jadi kami memiliki dua bidang $ 1 yang merupakan "1" dan $ 2 yang merupakan ruang kosong. ketika penerjemah tersandung pada garis yang mengandung ungkapan seperti itu (maksud saya 1); Output dari perintah "echo" adalah satu baris yang berisi "1" sehingga filter akan berfungsi ...

Ketika berhadapan dengan contoh berikut:

echo "1: " | awk '/1/ -F ":" {print $1}'

Sintaksnya berantakan dan interpreter memilih untuk mengabaikan bagian F ":" dan beralih ke bidang splitter standar yang merupakan ruang kosong sehingga menghasilkan "1:" sebagai bidang pertama dan tidak akan ada bidang kedua!

Jawaban JUERGEN berisi sintaks yang baik ...


3

Atau Anda dapat menggunakan:

echo "1: " | awk  '/1/{print $1-":"}' 

Ini persamaan yang sangat lucu.


1
apa /1/artinya

Temukan polanya. Dalam hal ini "1"
José Dias
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.