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
shantanuo
sumber
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)

glenn jackman
sumber
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
Mahmoud Abdelkader
sumber
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.

Bruno Bronosky
sumber
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 }'
shantanuo
sumber
0

Haruskah ini tidak berhasil?

echo "LOAD_SETTLED    LOAD_INIT       2011-01-13 03:50:01" | awk '{print $1}'
asadz
sumber