Awk'de sekmeyle ayrılmış değerler


92

SEKME ile ayrılmış dizeden ilk sütunu nasıl seçerim?

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

Yukarıdakiler, beklendiği gibi yalnızca "LOAD_SETTLED" değil, tüm satırı döndürecektir.

Güncelleme:

Sekmeyle ayrılmış değerlerdeki üçüncü sütunu değiştirmem gerekiyor. Aşağıdakiler çalışmıyor.

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

Ancak bu, ayırıcı sekme yerine virgül ise beklendiği gibi çalışır.

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} '# aradığım şey buydu. Google aramam doğru mu? :)
shantanuo

3
Bu yorum sayesinde şunu keşfettim: awk 'BEGIN {FS="\t"}; {print $1,FS,$2,FS,$3}' myFile.txtilk üç sütunun sekmeyle ayrılmış değerlerini yazdırmak.
Wok

7
Ya da belki basitçeawk 'BEGIN {OFS="\t"}; {print $1,$2,$3}'
Josiah Yoder

3
-vDeğişkenleri ayarlamak için hem GNU hem de BSD awk desteği . Satır içi bir programınBEGIN {FS="\t"} içinde kullanmak çirkin ve böyle yapmaya çalıştığınız herhangi bir açık kaynak katkısına muhtemelen itiraz edilebilir. Bunu yalnızca bir program dosyası yazıyorsanız yapın . Ayrıca, bunun yerine kullanılması tavsiye edilmez , çünkü ikincisi sadece ayarlandığını ve olmadığını açıkça ortaya koyar . Bu son nokta hakkındaki kafa karışıklığı, bu gönderiye ilk etapta neden oldu. Bu yüzden "iyi tarz" önemlidir. -F-v FS=FSOFS
Bruno Bronosky

1
Lütfen hiç kimse @Wok'un gösterdiği şeyi yapmamalıdır. Çıktınızda [Giriş] Alan Ayırıcılarını numaralandırmazsınız. OFSDeğişken aracılığıyla bir Çıktı Alanı Ayırıcısı belirtirsiniz .
Bruno Bronosky

Yanıtlar:


143

OFSDeğişkeni (çıktı alanı ayırıcısı) bir sekme olarak ayarlamanız gerekir :

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

( $lineecho ifadesinde değişkeni alıntı yaptığınızdan emin olun )


6
$ '\ T' içinde $ 'ın amacı nedir?
Amr Mostafa

10
Advanced Bash Komut Dosyası Yazma Kılavuzundaki kendi sorumu yanıtlamak : $ '...' tırnaklı dizge genişletme yapısı, kaçan sekizlik veya onaltılık değerleri kullanan bir mekanizmadır ... örneğin, tırnak = $ '\ 042'.
Amr Mostafa

5
@AmrMostafa, rehber değil mi düşünmek birini açan bir yanıltıcı açıklaması var çok kötü olduğunu $içinde $'\t'gerekli değildir. Greg'in wiki'si daha iyidir: "Bunlardan $'...'en yaygın olanıdır ve ters eğik çizgiden kaçan kombinasyonların ANSI C standardında belirtildiği gibi genişletilmesi dışında tek tırnak gibi davranır".
Cristian Ciupitu

9
Geriye dönüp bakıldığında, $'\t'gerekli değildir. awk dizenin "\t"sekme karakteri olduğunu anlıyor
glenn jackman

6
Açık Kaynak Katkıda Bulunanlar, yalvarıyorum, lütfen gibi şeyler göndermeyin awk -F $'\t' 'BEGIN {OFS = FS} …'. Bu olmalı awk -v FS='\t' -v OFS='\t' '…'. Bilgiçlikçi görünebilir, ancak tutarsız olmak, daha sonraki bir katılımcının kodunuzu yanlış anladıkları için bir hata getirme olasılığını artırır.
Bruno Bronosky

21

Gerçekten sekmeler olduklarından emin olun! Bash'de, kullanarak bir sekme ekleyebilirsiniz.C-v TAB

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


9

Kullanım:

awk -v FS='\t' -v OFS='\t' ...

Komut dosyalarımdan birinden örnek .

Sekmeyle ayrılmış BIND bölgesi dosyalarını işlemek için FSve OFSdeğişkenlerini kullanıyorum :

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

Bu, bunu yapmanın temiz ve okunması kolay bir yoludur.


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 }'

-2

Bu çalışmamalı mı?

echo "LOAD_SETTLED    LOAD_INIT       2011-01-13 03:50:01" | awk '{print $1}'
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.