Sebuah pertanyaan tentang awk


9

Ok, karena ini adalah pertanyaan yang kompleks, saya akan menjelaskannya dengan jelas. Saya mendapat konten file seperti di bawah ini:

$ Cat File1 
ABC Cool Lol POP {MNB}
ABC Cool Lol POP {MNB}
ABC Cool Lol POP {MNB}
ABC Cool Lol POP {TBMKF}
ABC Cool Lol POP {YUKER}
ABC Cool Lol POP {EFEFVD}

Output yang saya inginkan

-Cool MNB +  POP ;
-Cool MNB  + POP ;
-Cool MNB  + POP ;
-Cool TBMKF + POP ;
-Cool YUKER + POP ;
-Cool EFEFVD +POP ;

Pertama saya mencoba untuk mengambil kolom terakhir dari File1dan mencetaknya sed 's/[{}//g' File1 > File3

Setelah itu saya salin seluruh konten File1ke yang baruFile4

cp File1 File4

Setelah itu saya mengganti data di dalam File4dengan File3data (berarti data tanpa tanda kurung satu " File1kolom terakhir yang satu")

awk 'FNR==NR{a[NR]=$1;next}{$5=a[FNR]}1' File3 File4 >>File5 

Outputnya harus seperti ini

ABC Cool Lol POP MNB
ABC Cool Lol POP MNB
ABC Cool Lol POP MNB
ABC Cool Lol POP TBMKF
ABC Cool Lol POP YUKER
ABC Cool Lol POP EFEFVD

Akhirnya saya coba

awk -F " '{print - $2,$5 +,$4 ";"}‘ File5

Tetapi hasilnya tidak keluar seperti yang saya inginkan, hanya data yang mirip MNB semuanya terdaftar, yang lain tidak muncul (File satu kolom data terakhir),


Apakah Anda menggunakan gnu awk?
123

Saya tidak yakin apa yang Anda maksud. Tapi saya hanya seorang pengemis baru untuk menyentuh awk. Ini adalah tugas yang perlu saya lakukan, saya mencoba yang terbaik perlahan satu langkah ke satu langkah untuk melakukan itu berdasarkan pemahaman saya tentang awk.
heng960407

1
ketik awk --version, bagaimana hasilnya?
123

2
Ubah judul Anda menjadi sesuatu yang lebih spesifik untuk masalah Anda. Ini akan memudahkan orang lain yang memiliki pertanyaan serupa di kemudian hari untuk menemukannya. Saat ini "Pertanyaan tentang awk" sangat umum.
Tom Fenech

Jawaban:


16

Saya tidak tahu mengapa Anda menyalin hal-hal kiri dan kanan. Yang sederhana adalah

awk '{print "-" $2, substr($5,2,length($5)-2), "+", $4, ";"}' File1

Saya meletakkan -awal dan ;akhir.

Di antara kami mencetak

  • $2 karena kami menginginkannya apa adanya.
  • substring of $5, yang merupakan string tanpa karakter pertama dan terakhir. Kami melewatkan karakter pertama dengan mulai dari posisi 2 (awk selalu aneh tentang itu) dan meninggalkan karakter terakhir dengan hanya memilih substring yang dua karakter lebih pendek, daripada yang asli$5
  • yang +karena kita menginginkannya
  • lalu $4

Namun, saya tidak yakin apakah semua fungsi string ini khusus untuk GNU awk.


substr(string, 2)mengembalikan substring mulai dari karakter kedua, seperti cut -c2-, tail -n +2, sed '2,$'... Apa yang begitu aneh tentang itu?
Stéphane Chazelas

3
Perintah itu standar dan bahkan akan bekerja dengan yang asli awkdari tahun 70-an.
Stéphane Chazelas

@ StéphaneChazelas: Ah, saya sudah menunggu Anda :-) Biasanya kita mulai menghitung pada 0 yang berarti indeks 2 adalah posisi ketiga, tapi di sini posisi kedua ada di indeks 2. Terima kasih telah menjelaskan pertanyaan GNU yang tersisa.
Bananguin

@ Bananguin, di shell Unix dan utilitas seperti yang ditunjukkan dalam beberapa contoh di atas, kita mulai dari 1, bukan 0. Pengecualian yang paling penting adalah array ksh dan $ {var: offset} (keduanya disalin oleh bash). Semua array shell lainnya mulai dari 1. Lihat juga Apakah ada alasan mengapa elemen pertama dari array Zsh diindeks oleh 1 bukannya 0?
Stéphane Chazelas

7

Dengan sed

sed '
    s/\S\+\s/-/
    s/\(\S\+\s\)\{2\}{\(\S\+\)}/\2 + \1;/
    ' File1

Dan variasi awk

awk -F"[[:blank:]{}]+" '{print "-" $2, $5, "+", $4}' ORS=" ;\n" File1

6

Pekerjaan TXR mudah :

$ txr -c '@(repeat)
@a @b @c @d {@e}
@(do (put-line `-@b @e + @d ;`))
@(end)' -
ABC Cool Lol POP {MNB}
ABC Cool Lol POP {MNB}
ABC Cool Lol POP {MNB}
ABC Cool Lol POP {TBMKF}
ABC Cool Lol POP {YUKER}
ABC Cool Lol POP {EFEFVD}
[Ctrl-D][Enter]
-Cool MNB + POP ;
-Cool MNB + POP ;
-Cool MNB + POP ;
-Cool TBMKF + POP ;
-Cool YUKER + POP ;
-Cool EFEFVD + POP ;

Menggunakan TXR Lisp awk macro untuk mentransliterasikan solusi Awk:

 txr -e '(awk (t (prn `-@[f 1] @{[f 4] [1..-1]} + @[f 3] ;`)))'

Bidang ada dalam fdaftar, dan pengindeksan berbasis nol.


1
+1 untuk tampilan lump dan paling menangis! Bahasa itu HARUS bersaing dalam pcg (kode pemrograman golf)
Archemar

@Archemar TXR tidak bersaing dalam golf dengan sangat baik karena ada bahasa khusus yang dirancang untuk hal-hal yang melakukan hal-hal seperti menetapkan fungsi ke karakter individu, yang kemudian dapat dirangkai untuk mencapai komposisi.
Kaz


1
@ Kaz Apakah ada tutorial TXR di suatu tempat? Halaman manual tampaknya agak besar. Bagaimana kinerjanya dibandingkan dengan awk?
bli

1
@ bli GNU Awk adalah sesuatu seperti setidaknya 30 kali lebih cepat pada bidang dasar yang membelah melalui file besar daripada TXR awk macro, yang merupakan 220+ baris kode yang diinterpretasikan , termasuk loop keseluruhan untuk memproses sumber input menjadi rekaman dan bidang.
Kaz

3

Menggunakan awk paling mudah ketika $1,$2,...bidang sudah berisi string yang tepat yang ingin Anda gunakan. Pemisah bidang, jika berisi lebih dari satu karakter, ditafsirkan sebagai ekspresi reguler. Kami tidak perlu melakukan pencarian dan penggantian atau operasi substring untuk menyingkirkan {curly braces}. Kami hanya menghitung mereka sebagai bagian dari pembatas.

awk -F'[ {}]+' '{printf("-%s %s + %s ;\n", $2, $5, $4)}'

Menggunakan printfbukannya printjuga membuatnya menjadi sedikit lebih mudah untuk melihat bagaimana string akan diformat, tetapi jika Anda ingin memiliki print "-"$2,$5" + "$4";"bukan printf("-%s %s + %s ;\n", $2, $5, $4), itu pilihan.

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.