Nilai yang dipisahkan tab dalam awk


90

Bagaimana cara memilih kolom pertama dari string yang dipisahkan TAB?

# echo "LOAD_SETTLED    LOAD_INIT       2011-01-13 03:50:01" | awk -F'\t' '{print $1}'

Di atas akan mengembalikan keseluruhan baris dan bukan hanya "LOAD_SETTLED" seperti yang diharapkan.

Memperbarui:

Saya perlu mengubah kolom ketiga di tab nilai yang dipisahkan. Berikut ini tidak berhasil.

echo $line | awk 'BEGIN { -v var="$mycol_new" FS = "[ \t]+" } ; { print $1 $2 var $4 $5 $6 $7 $8 $9 }' >> /pdump/temp.txt

Namun ini berfungsi seperti yang diharapkan jika pemisahnya koma, bukan tab.

echo $line | awk -v var="$mycol_new" -F'\t' '{print $1 "," $2 "," var "," $4 "," $5 "," $6 "," $7 "," $8 "," $9 "}' >> /pdump/temp.txt

4
awk 'BEGIN {FS = "[\ t] +"}; {print $ 1} '# ini yang saya cari. Apakah pencarian google saya benar? :)
— shantanuo

3
Berkat komentar ini, saya telah menemukan: awk 'BEGIN {FS="\t"}; {print $1,FS,$2,FS,$3}' myFile.txtuntuk mencetak nilai tab-delimited dari tiga kolom pertama.
— Wajan

6
Atau mungkin sederhanaawk 'BEGIN {OFS="\t"}; {print $1,$2,$3}'
— Josiah Yoder

3
Baik GNU dan BSD mendukung -vvariabel pengaturan. Sangat buruk untuk digunakan BEGIN {FS="\t"}di dalam program sebaris , dan kontribusi sumber terbuka apa pun yang Anda coba buat seperti itu kemungkinan besar akan ditolak. Lakukan itu hanya jika Anda sedang menulis file program . Juga, tidak disarankan untuk menggunakan -Fdaripada -v FS=karena yang terakhir menjelaskan bahwa hanya FSsedang diatur dan tidak OFS. Kebingungan tentang poin terakhir itulah yang menyebabkan posting ini di tempat pertama. Itulah mengapa "gaya yang baik" itu penting.
— Bruno Bronosky

1
Tolong, tidak seorang pun, pernah, harus melakukan apa yang ditunjukkan @Wok. Anda tidak menghitung Pemisah Bidang [Input] di Output Anda. Anda menentukan Pemisah Bidang Keluaran melalui OFSvariabel.
— Bruno Bronosky

Jawaban:


141

Anda perlu mengatur OFSvariabel (pemisah bidang keluaran) menjadi tab:

echo "$line" | 
awk -v var="$mycol_new" -F $'\t' 'BEGIN {OFS = FS} {$3 = var; print}'

(pastikan Anda mengutip $linevariabel dalam pernyataan echo)


6
Apa tujuan dari $ in $ '\ t'?
— Amr Mostafa

10
Menjawab pertanyaan saya sendiri dari Panduan Pembuatan Skrip Bash Lanjutan : Konstruksi ekspansi string yang dikutip $ '...' adalah mekanisme yang menggunakan nilai oktal atau heks yang lolos ..., misalnya, kutipan = $ '\ 042'.
— Amr Mostafa

5
@AmrMostafa, sayang sekali panduan itu memiliki penjelasan yang menyesatkan yang membuat orang berpikir bahwa Anda tidak $masuk $'\t'tidak diperlukan. Greg's wiki lebih baik: "Dari ini, $'...'adalah yang paling umum, dan bertindak seperti tanda kutip tunggal kecuali bahwa kombinasi yang diloloskan dengan garis miring terbalik diperluas sebagaimana ditentukan oleh standar ANSI C".
— Cristian Ciupitu

9
Kalau dipikir-pikir, $'\t'itu tidak perlu. awk memahami string "\t"sebagai karakter tab
— glenn jackman

5
Kontributor Sumber Terbuka, saya mohon, jangan mengirimkan hal-hal seperti itu awk -F $'\t' 'BEGIN {OFS = FS} …'. Seharusnya begitu awk -v FS='\t' -v OFS='\t' '…'. Ini mungkin tampak terlalu berlebihan, tetapi menjadi tidak konsisten meningkatkan kemungkinan kontributor nantinya akan memperkenalkan bug karena mereka salah memahami kode Anda.
— Bruno Bronosky

21

Pastikan mereka benar-benar tab! Di bash, Anda dapat memasukkan tab menggunakanC-v TAB

$ echo "LOAD_SETTLED    LOAD_INIT       2011-01-13 03:50:01" | awk -F$'\t' '{print $1}'
LOAD_SETTLED


9

Saya menggunakan variabel FSand OFSuntuk memanipulasi file zona BIND yang dibatasi tab. Ini adalah salah satu skrip saya https://gist.github.com/RichardBronosky/abe1652c2d5c78c35b92ad02bdf0d0af#file-dns_update-sh-L36-L39

Dagingnya adalah:

awk -v FS='\t' -v OFS='\t' \
    -v record_type=$record_type \
    -v hostname=$hostname \
    -v ip_address=$ip_address '
$1==hostname && $3==record_type {$4=ip_address}
{print}
' $zone_file > $temp

Ini adalah cara yang bersih dan mudah dibaca untuk melakukan ini.


5
echo "LOAD_SETTLED    LOAD_INIT       2011-01-13 03:50:01" | awk -v var="test" 'BEGIN { FS = "[ \t]+" } ; { print $1 "\t" var "\t" $3 }'

0

Haruskah ini tidak berhasil?

echo "LOAD_SETTLED    LOAD_INIT       2011-01-13 03:50:01" | awk '{print $1}'
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.