列値条件でawkを使用する


108

私はAWKプログラミング言語からawkを学んでおり、例の1つに問題があります。

$ 2が値(たとえば1)と等しい場合に$ 3を出力したい場合は、次のコマンドを使用して問題なく動作します。

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

しかし、1を別の検索条件(たとえばfindtext)で置き換えると、コマンドは機能しません。

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

これは出力を返さず、入力ファイルに「findtext」が存在することを確認しています。

私もこれを試しましたが、うまくいきません:

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

これが 'test'という名前の私のテストファイルで、スペースで区切られた9行と8フィールドがあります。

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

これが私がしたことと出力です:

$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

私はこれが$ 3で、$ 8に "ClNonZ"が含まれていることを期待しています。

0.180467091 
0.010615711 
0.492569002

awkコマンドが何も返さなかった理由がわかりません。何かご意見は?


文字列値 "findtext"を引用符で囲む必要があります。それ以外の場合は、変数名です
evil otto

「findtext」を使用して二重引用符を試してみましたが、機能しません..それが私を困らせる理由です
user1687130

1
「動作しない」は何も教えてくれません。正確な入力、正確なコード、期待される出力、および実際の出力を示します。
chepner 2013

回答:


127

特定の文字列を探している場合は、引用符で囲みます。

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

そうでない場合、awkはそれを変数名であると想定します。


私はこれを試しましたが、うまくいきません。理由はわかりません。私はgrepで再確認しましたが、テキストはそこにありました。:(
user1687130 2013

1
@ user1687130、あなたは私たちにいくつかの入力例と期待される出力を示す必要があると思います。
Carl Norum、2013

1
データはスペースで区切られていますか?それらのスペースの一部はタブである可能性がありますか?awkを使用して単一のフィールドをエコーし​​てみてください。awk '{ print $8 }'あなたが期待する何を与えますか?
ロブ・デービス

1
それはのためにあるかもしれないAWK(とそれをチェックし、実装awk --version、それはで動作し、私の答えに見て、)GAWKMAWKあまりにも。
arutaku

これは、awkスクリプトを二重引用符で囲む場合は機能しません。いいねawk "$1 == \"findtext\" {print $3}"
Thirupathi Thangavel 2017

33

このメソッドは正規表現を使用しており、機能するはずです。

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

おかげで私はawkを使用して、悪魔的な方法とgrepを使用せずに$ NFで正規表現を見つける方法を探していました^^
Thibault Loison

20

AWK実装によっては、使用して==いるかどうかは問題ありません。

試しました~か?たとえば、$ 1を「こんにちは」にしたい場合:

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

^$ 1の開始を意味し、$$ 1の終了です。


4
すべてのawk実装は、「==」と「〜」の両方をサポートしています。
Ed Morton、

2
@EdMorton-OS Xはとのawk一致に失敗しました==が、で成功しました~
jww 2016年

2
@jww何と何を一致させるのに失敗しましたか?これらは同等です:$1 == "hello"$1 ~ /^hello$/。あなたはやるべきではありません$1 ~ "^hello$"、それは正規表現コンテキスト内の文字列を使っているとして、この答えのようにのでawkはそれを使用する前に、正規表現に文字列を変換する必要があり、それは副作用(男性のawkを)持っています。
Ed Morton 2016年

4

これは私にはもっと読みやすいです

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

2

私のawkバージョンは3.1.5です。

はい、入力ファイルはスペースで区切られ、タブはありません。

arutakuの回答によると、これが私が試した結果、うまくいきました:

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


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

何がうまくいかなかったのか(なぜかわからない、おそらく私のawkバージョンが原因です:)、

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

回答、コメント、助けてくれてありがとう!


9
これは、awkバージョンとは関係ありません。Windowsでテストファイルを作成したので、各行の最後に追加されたcontrol-Mを実行するために使用したiwhateverツールはClNonZ<control-M>、各行の最後のフィールドClNonZがであるため、grepまたは "〜 "awkでそれは見つかりますが、等価比較では見つかりません。
Ed Morton、

2
はい、理にかなっています。$ dos2unixテストを試してから、「==」を使用して「〜」を置き換えたところ、動作しました。説明ありがとう!
user1687130 2013

-3

これを試してください

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

または

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

残念なことに、この回答は実際にユーザーが具体的に要求したAwk構文を使用していません。
Asfand Qazi 2017
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.