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.