awk ile sütun değeri koşullarını kullanma


109

AWK Programlama Dili'nden awk öğreniyorum ve örneklerden biriyle ilgili sorun yaşıyorum.

$ 2 bir değere eşitse (örneğin 1) 3 $ yazdırmak istersem, iyi çalışan bu komutu kullanıyordum:

awk '$2==1 {print $3}' <infile> | more

Ancak 1'i başka bir arama kriteriyle değiştirdiğimde (örneğin findtext), komut çalışmıyor:

awk '$1== findtext {print $3}' <infile> | more

Hiçbir çıktı döndürmez ve eminim ki girdi dosyasında 'metin bul' vardır.

Bunu da denedim ama işe yaramıyor:

awk '$1== "findtext" {print $3}' <infile> | more

İşte 'test' adlı test dosyam ve içinde boşlukla ayrılmış 9 satır ve 8 alan var:

1 11 0.959660297 0 0.021231423 -0.0073 -0.0031 MhZisp
2 14 0.180467091 0.800424628 0 0.0566 0.0103 ClNonZ
3 19 0.98089172 0 0 -0.0158 0.0124 MhNonZ
4 15 0.704883227 0.265392781 0.010615711 -0.0087 -0.0092 MhZisp
5 22 0.010615711 0.959660297 0.010615711 0.0476 0.0061 ClNonZ
6 23 0.715498938 0 0.265392781 -0.0013 -0.0309 Unkn
7 26 0.927813163 0 0.053078556 -0.0051 -0.0636 MhZisp
8 44 0.55626327 0.222929936 0.201698514 0.0053 -0.0438 MhZisp
9 31 0.492569002 0.350318471 0.138004246 0.0485 0.0088 ClNonZ

İşte yaptığım şey ve çıktı:

$awk '$8 == "ClNonZ" {print $3}' test 

$ grep ClNonZ test 
2 14 0.180467091 0.800424628 0 0.0566 0.0103 ClNonZ
5 22 0.010615711 0.959660297 0.010615711 0.0476 0.0061 ClNonZ
9 31 0.492569002 0.350318471 0.138004246 0.0485 0.0088 ClNonZ

Bunun 8 $ 'ında "ClNonZ" bulunan 3 $ olduğunu görmeyi umuyorum.

0.180467091 
0.010615711 
0.492569002

Awk komutunun neden hiçbir şey döndürmediğini bilmiyorum. Düşüncesi olan var mı?


"Findtext" dize değerini tırnak içine almanız gerekir, aksi takdirde bu bir değişken adıdır
evil otto

"Findtext" ile çift tırnak denedim, ama işe yaramıyor .. bu yüzden beni rahatsız ediyor
user1687130

1
"Çalışmıyor" bize hiçbir şey söylemez. Bize kesin girdileri, kesin kodu, beklenen çıktıyı ve gerçek çıktıyı gösterin.
chepner

Yanıtlar:


129

Belirli bir dizeyi arıyorsanız, etrafına tırnak işaretleri koyun:

awk '$1 == "findtext" {print $3}'

Aksi takdirde, awk bunun bir değişken adı olduğunu varsayacaktır.


Bunu denedim ama işe yaramıyor neden bilmiyorum. Grep ile iki kez kontrol ettim ve metin oradaydı. :(
user1687130

1
@ user1687130, sanırım bize bazı örnek girdiler ve beklenen çıktılar göstermeniz gerekecek.
Carl Norum

1
Verilerinizin boşlukla ayrılmış olduğundan emin misiniz? Bu boşluklardan bazıları sekme olabilir mi? Tek bir alanı yankılamak için awk kullanmayı deneyin. Does awk '{ print $8 }'beklediğiniz size?
Rob Davis

1
Uygulama nedeniyle olabilir AWK(ile kontrol edin awk --version), cevabıma bir göz atın, işe yarıyor GAWKve MAWKde.
arutaku

Bu, awk komut dosyası etrafında çift tırnak kullandığımızda işe yaramaz. Likeawk "$1 == \"findtext\" {print $3}"
Thirupathi Thangavel

34

Bu yöntem regexp kullanır, çalışmalıdır:

awk '$2 ~ /findtext/ {print $3}' <infile>

Teşekkürler, şeytani yöntemler kullanmadan $ NF'de normal ifadeyi bulmak için awk kullanmanın bir yolunu arıyordum ve grep ^^
Thibault Loison

20

Uygulamaya bağlı AWKolarak iyi mi kullanıyorsun ==.

Denedin ~mi Örneğin, $ 1'in "merhaba" olmasını istiyorsanız:

awk '$1 ~ /^hello$/{ print $3; }' <infile>

^1 $ başlangıç ​​ve $1 $ bitiş anlamına gelir .


4
Tüm awk uygulamaları hem "==" hem de "~" destekler.
Ed Morton

2
@EdMorton - OS X en awkile eşleşecek şekilde başarısız ==, ama başarılı oldu ~.
jww

2
@jww Ne ile neyle eşleşemedi? Bunlar eşdeğerdir: $1 == "hello"ve $1 ~ /^hello$/. $1 ~ "^hello$"Bir regexp bağlamında bir dizge kullandığından ve bu nedenle awk'ın kullanmadan önce dizeyi bir regexp'e dönüştürmesi gerektiğinden ve yan etkileri olduğundan (man awk) bu yanıtta gösterildiği gibi asla yapmamalısınız .
Ed Morton


2

Awk sürümüm 3.1.5.

Evet, girdi dosyası boşlukla ayrılmış, sekme yok.

Arutaku'nun cevabına göre, işe yarayan şey şu:

awk '$8 ~ "ClNonZ"{ print $3; }' test  
0.180467091
0.010615711
0.492569002


$ awk '$8 ~ "ClNonZ" { print $3}' test  
0.180467091
0.010615711
0.492569002

Ne işe yaramadı (nedenini bilmiyorum ve belki awk sürümümden dolayı :),

$awk '$8 ~ "^ClNonZ$"{ print $3; }' test
$awk '$8 == "ClNonZ" { print $3 }' test

Cevaplarınız, yorumlarınız ve yardımlarınız için hepinize teşekkür ederiz!


9
Bunun sizin awk sürümünüzle hiçbir ilgisi yoktur. Test dosyanızı Windows'ta oluşturdunuz, bu nedenle, bunu yapmak için kullandığınız araç ne olursa olsun, her satırın sonuna control-Ms ekliyordu, böylece her satırdaki son alan, grep veya "~ ile yapıldığı gibi bir RE kısmi eşleşme karşılaştırması ClNonZ<control-M>değil ClNonZbu yüzden "awk onu bulur, ancak eşitlik karşılaştırması bulamaz.
Ed Morton

2
Evet, mantıklı. $ Dos2unix testini denedim ve "~" yerine "==" kullandım ve işe yaradı. Açıklama için teşekkürler!
user1687130

-3

lütfen bunu dene

echo $VAR | grep ClNonZ | awk '{print $3}';

veya

echo cat filename | grep ClNonZ | awk '{print $3}';

Maalesef bu cevap, kullanıcının özellikle istediği Awk sözdizimini kullanmıyor!
Asfand Qazi
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.