awkについての変更方法とエラーの原因

このQ&Aのポイント
  • awkコマンドで変数をコマンドラインから渡す方法について調べています。ウェブで調べたところARGVを使用することが分かりましたが、実行時に引数を与えるとファイル名として認識されるエラーが発生しています。
  • awkコマンドを使用して8番目のフィールドが特定の条件に一致する場合に9番目のフィールドの合計と平均を計算するスクリプトを作成しています。ただし、条件に一致するデータが存在しない場合の処理も行っています。
  • awkコマンドを使用して変更したいデータの条件をコマンドラインから指定できるようにしたいです。具体的には、○○○というデータではなく、コマンド実行時に引数として渡したいです。変更を試みたところ、エラーが発生してしまいます。
回答を見る
  • ベストアンサー

awkについて

度々すみません。awkについて先程教えて頂いたものですが、少し変更しようと思っているのですが上手くいきません。変更していることは、以下の○○○の内容を固定ではなくてコマンドラインから渡したいです。 ウェブで調べたところARGVというのを使うことはわかりました。そこで"○○○"からARGV[0]に変更してコマンド実行時に引数を与えたのですが、「○○○というファイルを開けません」というエラーになってしまいます。実行したのはawk -f awk data.csv ○○○です。なぜ引数をファイル名だと認識してしまうのでしょうか。初歩的で申し訳ありませんが教えて下さい。 BEGIN{ goukei = 0 count = 0 } { #フィールドの8番目の条件が一致する場合のみ9番目を合計 if($8=="○○○"){ goukei += $9 count++ } } END{ if(count!=0){ print "合計は", goukei print "平均は", goukei/count } else{ print "条件に一致するのない” } }

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

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

>なぜ引数をファイル名だと認識してしまうのでしょうか。 そりゃ簡単。 大雑把に言って、awkは最後のオプション(そのオプションが引数をとるなら その引数)の後は すべて処理対象のファイルの名前と見なすからです。 #実は例外があるけど割愛。 じゃあどうすれば、というと awk -f sample.awk data.csv ○○○ この順番をひっくり返して awk -f sample.awk ○○○ data.csv にしたうえでスクリプトのBEGINブロックで target = ARGV[1] ARGV[1] = "" というのを付け加えて、 ルールを { #フィールドの8番目の条件が一致する場合のみ9番目を合計 if($8=="○○○"){ if ($8 == target) { に変更してください。 ちなみに、ARGV[0]ってのはawkインタプリタの名前が入ってるもので 引数じゃありません(引数は1から)。 あるいは、 awk -f sample.awk -vtarget='○○○' data.csv のようにします。 こちらだと if 文の修正は必要ですが、BEGINブロックの修正はいりません。

rio_grande
質問者

お礼

ご丁寧に有り難うございました。出来るようになりました。

関連するQ&A

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

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

  • awkについて

    UNIXのawkコマンドにて、レコードを抜き出したいのですが、その時抜き出した各レコード毎に改行 をいれたいのですが、下記のような定義で問題ないでしょうか? awk -f PGMファイル 元データファイル > 抜き出したデータファイル PGMファイル は下記です。 BEGIN{ORS=\"\\n\"}  ←改行でいいんでしょうか? { if(substr($0, 5, 1) == \"1\"){ if(substr($0, 6, 2) == \"2\"){ print substr($0, 1,138) } } }

  • awkの使い方について教えてください。

    awkとperlなどの初心者です。 使い方が分かっていないのですが、 例えば出力のフィールドセパレータを,に変更するには どうすればいいでしょうか? awk '{OFS=,;print}' fileなどとやってみますが、 うまくいきません。2つ以上のコマンドを実行するときの 文法がわかっていないような気がするのですが。 あとperlでよくみかけるperl -neのnは何でしょうか? man perlとやってみても-wと-eの意味しかのっていなくて なからないのですが。ご教授下さい。

  • 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" のような情報があります。(フィールドの区別は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 の使い方

    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によるあるプログラムその2

    立て続けに申し訳ないですが、 次のプログラムを実行すると、 gawk: ./test.awk:19: fatal: function name `foo' previously defined というエラーになってしまいます。 なぜでしょうか? #!/usr/bin/gawk -f #test.awk: BEGIN{ a="OK"; b="OK"; c="OK"; print foo(1,2); print a,b,c; print bar("AWK is", "convenient"); print a,b,c; print "4!==" recursive(4); } function foo(a,b, c){ c=a+b; return c; } function foo(a,b, c){ c=a b; return c; } function recursive(a){ if(a<=1)return 1; else return a*recursive(a-1); }

  • PowerShell で bash の awk 的な事

    PowerShellで下記のコマンドと同じような事がしたいです。 どのたかご教示ください。 awk '{print $1}' hoge.txt awk -v str="${hoge}" '{if($1==str) print $0}' hoge.txt awk '{print length($1)}' ヒントでも構いません、 よろしくお願い致します。

  • AWKスクリプトについて

    AWKスクリプトで あるファイルの中の3単語目の最大文字数を表示させたくて以下のようなスクリプトを作成しました。 #!/bin/nawk -f BEGIN{ maxword = 0; } { if( length( $3 ) > $maxword ) maxword = length( $3 ); } END{ print $maxword; } 単純なスクリプトなのですが, テストしてみると空白の出力しかされません。 なにか間違っているのでしょうか? どなたかアドバイスをお願いします。

  • コードがうまく作れません

    iの値に一致するセルをAK列のセルから探し出し、一致したら同じ行のセルBA列の値を合計します。iの合計が出たらワークシート2にiの値と合計をセルに貼り付けます。 次にiの値を1増やしてまた同じセルを探し出し、合計を出してワークシートの下の行のセルへ貼り付けます。 これで実行すると合計が全て0になります。どうかご指導をお願いします。 Sub sou() Dim h, count, goukei, i, e, f h = 1 e = 1 f = 1 count = 0 goukei = 0 Worksheets("Sheet1").Activate Worksheets("Sheet2").Activate For i = 12345 To 45787 For h = 1 To Cells(Rows.count, "AK").End(xlUp).Row If i = Cells(h, "AK") Then count = Cells(h, "BA") goukei = count + goukei End If Next h Worksheets("sheet2").Cells(e, "A") = i Worksheets("sheet2").Cells(f, "B") = goukei e = e + 1 f = f + 1 Next i End Sub

専門家に質問してみよう