• ベストアンサー

awkについて

awkについて 今とあるファイルの/var/tmp/test 中の検索についてawkを使用しています。 123 abc 123-m 333 aaa-xx 1qwoko などタブキーで区切られています。 cat /var/tmp/test grep 123 | awk '$=="123"{print $2}' とやった場合存在するので 結果がでるのですが、その結果がない場合"NG"など文字列を出したいのですがどうすればいいでしょうか?

質問者が選んだベストアンサー

  • ベストアンサー
  • taka37777
  • ベストアンサー率30% (166/544)
回答No.1

awk 'BEGIN{find=0}($0~/123/){print $2;find=1}END{if(find==0)print "NG\n"}' ファイル名 ではどうでしょうか? -------------------- a.txtの内容 123 abc 123-m 333 aaa-xx 1qwoko -------------------- # awk 'BEGIN{find=0}($0~/123/){print $2;find=1}END{if(find==0)print "NG\n"}' a.t xt abc 333 -------------------- b.txtの内容 23 abc 23-m 333 aaa-xx 1qwoko -------------------- # awk 'BEGIN{find=0}($0~/123/){print $2;find=1}END{if(find==0)print "NG\n"}' b. txt NG

ok_papa
質問者

補足

返信ありがとうございます。 もう少し、質問があります。あまり、正規表現とかメタ文字とかがわかっていないのかもしれませんが。 このプログラムの意味をもう少し教えてください。 例えば、始めに私が記述した方法ですと、 1列目に"123"という文字列がある行の2列目がでてきますよね? abc これはなんかBIGINとかfindを使用してますがもう少し説明のほどお願いします。 find=0とfind==0とはどういういみでしょうか?

その他の回答 (3)

  • kmee
  • ベストアンサー率55% (1857/3366)
回答No.4

まず、お使いのシェルはなんでしょうか? bash,kshの場合、 "\t" は無変換でそのまま、バックスラッシュとtになります。 $'\t' や $"\t" とすると、水平タブ文字に変換されます。 シングルクォートとダブルクォートは、それぞれ従来と同じです。 zshなら"\t"で水平タブ文字になります。 tcsh,cshでは、マニュアルにそれらしき記述が見つかりませんでした。 '\s','\t' (いずれも、バックスラッシュ+1文字)はgrepでは定義されていません。 [[:space:]]は、下を見る限り対応していそうなんですが。 http://www.kt.rim.or.jp/~kbk/regex/regex.html#GREP http://docs.sun.com/app/docs/doc/816-5175/regex-5?l=en&a=view

ok_papa
質問者

お礼

ありがとうございます。

  • sakusaker7
  • ベストアンサー率62% (800/1280)
回答No.3

> やりたいことは、1列目の文字列を完全一致で検索したいんです。 > '$1=="123" ああ、1 が抜けていたのですね。 > ちなみに、[[:space:]]や/tなどつかって後ろがタブ文字などつかってもなぜか、うまく取得できませんでした。 /t は \t のうち間違いではなく本当にそう入力したのですか? 昔のものだと本当にタブコードで入れないといけないものもありましたが Solarisのなら \t を受け付けると思うのですが。 [[:space:]] もだめというのもわかりませんねえ。確かに Solarisコマンドは 癖があるのが多いのですけど。

ok_papa
質問者

お礼

ありがとうございます。

ok_papa
質問者

補足

度々ありがとうございます。もう少し説明すると Solaris上のコマンドで grep "^123[実際にTABキーを入れる]" /ファイル名 これだと 123 xxxxxx などでます。 grep "^123\t" ~ だと表示されません。また grep "^123[[:space:]]"~ でも表示されませんでした。 単純に grep \t ~やgrep \s~のみだけだと、空白行?Tab?が含むものはすべて出てきました。 単純に書き方が悪いだけなのでしょうか?

  • sakusaker7
  • ベストアンサー率62% (800/1280)
回答No.2

>'$=="123" ここ、なにをしようとしているのでしょう? タブで区切られた行の先頭要素ですか? 行の先頭に123があるかどうかでいいのならawkを使わずに grep -e '^123' /var/tmp/test > /dev/null としてgrepのexit statusを見ればあったかどうかを確認できます。 2.3 Exit Status =============== Normally, the exit status is 0 if selected lines are found and 1 otherwise. But the exit status is 2 if an error occurred, unless the `-q' or `--quiet' or `--silent' option is used and a selected line is found. Note, however, that POSIX only mandates, for programs such as `grep', `cmp', and `diff', that the exit status in case of error be greater than 1; it is therefore advisable, for the sake of portability, to use logic that tests for this general condition instead of strict equality with 2.

ok_papa
質問者

お礼

ありがとうございます

ok_papa
質問者

補足

返信ありがとうございます。 やりたいことは、1列目の文字列を完全一致で検索したいんです。 '$1=="123" grep -e '^123' で実際にやってみると 123 xxxxx 123-xxx xxxxx 123abc aaaaa など出てきてしまい、-w,-eなどうまくつかえませんでした。 ちなみにOSはSolaris10上でやっています。 なにか単純に書き方がわるいだけなのでしょうか? もう少し教えていただけることがありましたら教えてください。 ちなみに、[[:space:]]や/tなどつかって後ろがタブ文字などつかってもなぜか、うまく取得できませんでした。

関連するQ&A

  • awkのセパレータ指定について

    awkのセパレータ指定について教えてください。 以下のようなファイルがありそれを'||'区切りで出力したいです。 下記のような指定をしてみたのですが、 うまくいきませんでした。 cat text | awk -F '||' '{print $1}' [test.txt] aaa||bbb||ccc [期待する結果] print $1 → aaa print $2 → bbb print $3 → ccc どなたか教えてください。 よろしくお願いします。

  • awkで可変文字列をマッチング

    シェルなどでawkを使う際に、シェルの引数として渡された文字列をawkに渡し、それを条件にマッチングをかけたいのですが、どうしたら良いのでしょうか?(まあ、素直にgrepを使えばいいのですが・・・) 例えば、 cat foo.txt | awk '{if ($2 == ptn) print}' ptn=$<シェルの引数> とかやれば、2番目のフィールドに完全に一致する行が抽出できるのですが、 cat foo.txt | awk '/ptn/ {print}' ptn=$<シェルの引数> とかやっても、"ptn"という文字列をマッチングしてしまうので、うまくいきません。どの位置に出現するかわからないけど、シェルの引数で指定された文字列が含まれている行だけを出力したい場合、どうしたらよいのでしょう・・・。

  • awkコマンドに引数を渡す方法

    awkコマンドに対して引数を渡す方法が知りたいです。 例えば以下のようなリストファイルがあったとします。 --------------------------------------- % cat test.lst 454 100 37536 200 32432 300 34q2 400 --------------------------------------- そこで以下のシェルを実行すると --------------------------------------- #!/bin/sh for VAL in 100 200 300 do CNT=`cat test.lst | awk '$2 == $VAL {print $1}'` echo "$VAL : $CNT" done --------------------------------------- awkコマンド内の$VALが引数ではなく文字列として認識されてしまうため、 出力結果が 100 : 200 : 300 : となってしまいます。 100 : 454 200 : 37536 300 : 32432 という結果を出力したい場合(awk内の引数を有効にする場合)どうすればよいでしょうか? awkを使用しない方法もあるかと思いますが、今回はawkを使った方法を知りたいです。 宜しくお願い致します。

  • awk の使い方

    sample.txt ファイルには   "中村" "08/01/80" "03.1234.5678"   "木村" "08/01/81" "06.1252.2536" のような情報があります。 そこの3番フィールドが電話番号ですので、awkで検索しようと思っています。 それで、 awk -v ARGU="$NUM" ' { VAR=substr($3,2,(length($3)-2)) if ( ARGU == VAR ) {print} }' /sample.txt のようにして、検索をかけようとしましたが、できません。 どこが間違っているのか教えてください。 awkの他の方法があるとか、違うもの(sed or grep)でできるのであれば、お願いします。

  • [awk]マッチしたものをすべて取り出したい

    awk(GNU awk)を使って正規表現にマッチした部分文字列を最初にマッチしたものだけでなく、すべて取り出したいと思っています。 grepコマンドを使うと次のように簡単に取得できるのですが、awkだけで実現する場合どのように記述したらよいのでしょうか? ■例 $ echo 'abcdebx' | grep -o 'b.' 結果: bc bx # 最初にマッチしたものだけなら取得できる $ echo 'abcdebx' | awk 'match($0, /b./) {print substr($0, RSTART, RLENGTH)}' 結果: bc ■環境 GNU Awk 4.0.1 よろしくお願いします。

  • awkで一つマッチしたら終了させる

    echo $var | awk '{ for (i = 0; i < NF; i++) { if ($i == "AAA") { j = i+1; print $j ; exit; } } }' として変数1"$var"から"AAA"という文字列を抜き出しているのですが $varに二個以上のAAAが存在するときに 一つめのAAAとマッチしたら終了としたいのです どの用にしたらよいでしょうか? ご教授お願いします。

  • awk の使い方

    sample.txt ファイルには   "中村" "08/01/80" "03.1234.5678"   "木村" "08/01/81" "06.1252.2536" のような情報があります。(フィールドの区別はTabです) そこの3番フィールドが電話番号ですので、awkで検索しようと思っています。 それで、 $ shell 06.1252.2536 #!/bin/sh NUM=$1                    #引数をNUMに代入 awk -v ARGU="$NUM" ' { VAR=substr($3,2,(length($3)-2))      #「"」を取り除いた if ( ARGU == VAR ) {print}         #電話番号と比較 }' /sample.txt のようにして、検索をかけようとしましたが、できません。 どこが間違っているのか教えてください。 awkの他の方法があるとか、違うもの(sed or grep)でできるのであれば、お願いします。

  • シェルスクリプトで、空白(スペース)を含む変数をawkに渡したいのです

    シェルスクリプトで、空白(スペース)を含む変数をawkに渡したいのですが、どうしたらいいでしょうか? 例えば、以下のようなtest.shというファイルを作ったとします。 --------------- #!/bin/sh AAA="x y" echo "" | awk '{print $AAA}' -------------- としたとき、$AAAが正常に出力できません。(なお、echo "" は、awkを走らせる為の単なるダミーです。) printの部分を ・awk '{print '$AAA'}' ・awk '{print "'$AAA'"}' などともしてみましたが、ダメでした。どのようにすればうまくいくでしょうか?

  • awk外で宣言した変数の参照

    kshを使用して、以下のようなシェルを作成しています。 しかしawk内で$iと$iiが参照出来てない様子です。 どのようにすれば参照できますでしょうか。 ■シェルの中身 #/usr/bin/ksh for i in `cat /tmp/hoge |awk -F : '{ print $3 }' | sort | uniq -d` do if [ $i != "" ]; then for ii in `cat /tmp/hoge` do echo $ii |awk -F ":" '{ if ( $3 -eq $i ) print $ii }' done fi done ■エラー awk: 0602-562 フィールド $() が正しくありません。 入力の行番号は 1 です。 ソースの行番号は 1 です。

  • awk 正規表現を使って置換

    あるファイルの中の2列目に含まれる "ab" "ac" "ae" という文字列をそれぞれ "zb" "zc" "ze"に置き換えたいのですが、awkまたはsedで正規表現を使って効率のいい方法はないでしょうか。 awk ' { gsub(/ab/,"zb",$2); gsub(/ac/,"zc",$2); gsub(/ae/,"ze",$2); print }' testfile でやりたいことはできるのですが、「aの後にb,c,eが続く場合にaをzに置換する」というアイディアを使えばもっと効率のよいスクリプトが書けるはず、と思いつつ、awkの勉強を始めたばかりでなかなか思い浮かびません。 testfileの中身は以下の通り: abcde abaab aaaae acbec accee adabd dceba aeecs hhhgf sbacc 以下のような出力を望んでいます: abcde zbazb aaaae zcbec accee adzbd dceba zeecs hhhgf sbzcc awk ' BEGIN { var = "[bce]" } { gsub("a"var,"z"var,$2); print }' だと "zb" "zc" "ze"ではなくすべて"z[bce]"に置き換わってしまうし、 awk ' BEGIN { var = "[bce]" } { gsub("a"var,"z&",$2); print }' だと"zab" "zac" "zae"になってしまうし… まずはawk,sedで勉強したいと思っていますが、それ以外でもいい案がありましたら教えてください。よろしくお願いします。

専門家に質問してみよう