• ベストアンサー

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

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

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

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

> awkで複数行に分けて書いてあるのは意味があるのでしょうか? awkの種類にもよりますが、 awk 'BEGIN { OFS = "," } {print $1,$2}' と書くとエラーになる場合があります。 #1の方の理由がそうだとはわかりませんが。 > また関数などを使い複数のコマンドを実行しようとして > うまくいかなかったのですが、書式はどうすればよいでしょうか? > awk '{コマンドA;コマンドB}'それとも > awk '{コマンドA}{コマンドB}'といった感じでしょうか? {} は一つの条件に対するアクションになります。 上記の例では同じ結果になるでしょうが、 条件が同じなら一つのアクションにまとめて awk '{foo=複雑な計算; print "ほげほげ:" , foo} のようにした方が明快です。 awk入門 http://www.eco.osakafu-u.ac.jp/~kazuhisa/awk.htm AWKとは http://aoki2.si.gunma-u.ac.jp/Hanasi/Algo/awk.html AWK Language Programming http://www.kt.rim.or.jp/~kbk/gawk-30/

vivi0303
質問者

お礼

ありがとうございます。 リンクを参照して勉強してみます。^^

その他の回答 (6)

  • mac_res
  • ベストアンサー率36% (568/1571)
回答No.7

No.1です。 >前に文字はなくてもよいのでしょうか? すみません。 動作するものの良くない例を例を示してしまいました。

  • mac_res
  • ベストアンサー率36% (568/1571)
回答No.6

No.1です。 >awk '//{コマンドA};//{コマンドB}'とした場合は シンタックスが間違っています。 awk '/pat1/{command1;} /pat2/{command2;}' awk ' /+/ {printf ("%d+%d=%d\n",$1,$3,$1+$3);} /-/ {printf ("%d-%d=%d\n",$1,$3,$1-$3);}' 1 + 2 1+2=3 5 - 2 5-2=3

vivi0303
質問者

お礼

何度もありがとうございます。 awk ' /+/ {printf ("%d+%d=%d\n",$1,$3,$1+$3);} /-/ {printf ("%d-%d=%d\n",$1,$3,$1-$3);}' がわかりません。 正規表現の前の一回以上の繰り返しを現す+ですよね? 前に文字はなくてもよいのでしょうか?

  • mac_res
  • ベストアンサー率36% (568/1571)
回答No.5

No.1です。 >回答いただいた内容で、awkで複数行に分けて書いてあるのは意味があるのでしょうか? BEGIN {}は、最初の行が読み込まれる前に実行されます。 OFS=","のような初期化は、最初の行が読み込まれる前に1回実行すればよいので、このように分けて書きました。 >また関数などを使い複数のコマンドを実行しようとしてうまくいかなかったのですが、書式はどうすればよいでしょうか? >awk '{コマンドA;コマンドB}'それともawk '{コマンドA}{コマンドB}'といった感じでしょうか? 当然、{コマンドA;コマンドB}です。 awk ' {printf ("%d+%d",$1,$2); printf ("=%d\n",$1+$2)}' を実行してみてください。

vivi0303
質問者

お礼

ありがとうございます。 awk '//{コマンドA};//{コマンドB}'とした場合は 別々のパターンを指定できるのでしょうか?

  • maura
  • ベストアンサー率46% (48/104)
回答No.4

オプションについては、こちらで簡単にまとまっています http://www.graco.c.u-tokyo.ac.jp/~nishi/programming/perl/option.html http://sonic64.com/2003-06-04.html 昔 awk でCGIも書いたことがあります。 awk は楽しいですよ

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

> あとperlでよくみかけるperl -neのnは何でしょうか? > man perlとやってみても-wと-eの意味しかのっていなくて > なからないのですが。ご教授下さい。 perl のことを調べるのなら perldoc コマンドを使った方が詳しい情報が得られます。 今回の場合なら perldoc perlrun とすれば NAME perlrun - how to execute the Perl interpreter SYNOPSIS perl [ -sTtuUWX ] [ -hv ] [ -V[:*configvar*] ] [ -cw ] [ -d[t][:*debugger*] ] [ -D[*number/list*] ] [ -pna ] [ -F*pattern* ] [ -l[*octal*] ] [ -0[*octal/hexadecimal*] ] [ -I*dir* ] [ -m[-]*module* ] [ -M[-]*'module...'* ] [ -f ] [ -C [*number/list*] ] [ -P ] [ -S ] [ -x[*dir*] ] [ -i[*extension*] ] [ -e *'command'* ] [ -- ] [ *programfile* ] [ *argument* ]... で始まるドキュメントが表示されます。 perldocコマンドはperlがインストールされていれば 使えるようになっているはずです。 今回のようなコマンドラインオプションなら、 perl -h とすれば -0[octal] specify record separator (\0, if no argument) -a autosplit mode with -n or -p (splits $_ into @F) -C[number/list] enables the listed Unicode features -c check syntax only (runs BEGIN and CHECK blocks) -d[:debugger] run program under debugger -D[number/list] set debugging flags (argument is a bit mask or alphabets) -e program one line of program (several -e's allowed, omit programfile) -f don't do $sitelib/sitecustomize.pl at startup -F/pattern/ split() pattern for -a switch (//'s are optional) -i[extension] edit <> files in place (makes backup if extension supplied) -Idirectory specify @INC/#include directory (several -I's allowed) -l[octal] enable line ending processing, specifies line terminator -[mM][-]module execute "use/no module..." before executing program -n assume "while (<>) { ... }" loop around program -p assume loop like -n but print line also, like sed -P run program through C preprocessor before compilation -s enable rudimentary parsing for switches after programfile -S look for programfile using PATH environment variable -t enable tainting warnings -T enable tainting checks -u dump core after parsing program -U allow unsafe operations -v print version, subversion (includes VERY IMPORTANT perl info) -V[:variable] print configuration summary (or a single Config.pm variable) -w enable many useful warnings (RECOMMENDED) -W enable all warnings -x[directory] strip off text before #!perl line and perhaps cd to directory -X disable all warnings というのが画面に出てきます。 最後に、 > ご教授下さい。 こういう場合に使うのは「教示」です。

vivi0303
質問者

お礼

ありがとうございます。参考にしてみます。^^

  • mac_res
  • ベストアンサー率36% (568/1571)
回答No.1

>awk '{OFS=,;print}' fileなどとやってみますが、うまくいきません。 awk ' BEGIN { OFS = "," } {print $1,$2}' のように使います。 123 456と入力すると、123,456になります。 >perl -ne -nは自動ループです。 while (<>) { ... # ここでスクリプトが実行される }

vivi0303
質問者

お礼

ありがとうございます。 回答いただいた内容で、awkで複数行に分けて書いてあるのは意味があるのでしょうか? また関数などを使い複数のコマンドを実行しようとして うまくいかなかったのですが、書式はどうすればよいでしょうか? awk '{コマンドA;コマンドB}'それともawk '{コマンドA}{コマンドB}'といった感じでしょうか?

関連するQ&A

  • perlでawkのようなことはできるでしょうか?

    perlなど初心者です。 awkでレコードのフィールドを$1、$2などと参照できるのが便利だなと感じているのですが、perlでもコマンドラインで同じ事をするにはどうすればよいでしょうか?

    • ベストアンサー
    • Perl
  • 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 "条件に一致するのない” } }

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

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

  • Bシェルのawkコマンドについて

    Bシェルのawkコマンドについてですが、例えばプロンプトから % ls -l hoge.txt | awk '{print $5}' と入力すると、hoge.txtのファイルサイズが出力されますが、同様のことをBシェルの中で行おうと思っています。 下記のように、配列arrayにはスペース区切りで3つのデータが入っており、N番目のデータを取得したいという場合に、Nに変数を使用して取得する方法がわかりません。 #!/bin/sh array="AA BB CC" num=3 # CCを取得したい echo $array | awk '{print $num}' 上記で実行すると、"AA BB CC"のようにすべて出力されてしまいます。awkで出力する箇所を${数値}で指定すればうまくいくのですが、ランダムで決めた数値(1~3)をnumに入れて取得したい場合、このようなことは可能でしょうか。 もし不可能な場合でも、awk以外に何かコマンドがあればご教授願います。なお、作成するのはBシェルになります。

  • awkのgsubによる置換

    awkのgsubで置換をしているのですが、置換後、全体をprintするため $0で出力したところ、セパレータがカンマ区切りから半角スペースに なってしまいます。 置換されなかった場合は、何事もなくそのまま出力されます。 これは、そのようなものなのでしょうか もし、カンマ区切りで出力したい場合は、ループなどで繰り返して 出す以外ないのでしょうか gawk -F"," '{if ($5=="1") {gsub($2,'abc',$2); print $0} else {print $0}}' hoge.txt

  • 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のフィールド数制限について質問です

    ご存知の方がいましたら、教えて下さい。 SunOS5.8でawkコマンドを実行すると、 1レコードが100フィールドを超えると、 「フィールド指定が多すぎます」のエラーがでるようなんですが、 SunOS5.8のawkは、1レコードが100フィールドまでした対応してないんでしょうか? また、nawkの場合の1レコードのフィールド数制限はあるのでしょうか? もし、パッチなどをあてて対応できるんであれば、教えて下さい。 よろしくお願いします。

  • awkコマンドについて

    教えてください。 Solaris9を使用しています。 SYSTEM Vでawkコマンドを使用しているシェルをSolaris9上で実行すると awk: レコード `従業員番号 従業員氏名 ...' においてフィールド指定が多すぎます。 のMSGが表示されてしまいます。 Solaris9では、1レコードの長さやフィールド数に制限があるのでしょうか? 行っている処理はテキストファイルのタブをカンマに変換です。 SYSTEM V上では正常に動作します。 よろしくお願いします。

  • awkで¥をエスケープする方法

    awkで以下のように文字列置換したいのですが、変数strA内で¥マークを使用すると正常に置換してくれません。どのようにエスケープすれば良いのでしょうか? ================================================= --実行コマンド---------- gawk -f CNV.awk input.txt --input.txt---------------- いぬ¥ねこ --CNV.awk---------------- strA="ぬ¥ね"; strB="★"; gsub(strA, strB, $0); print $0; ================================================= このとき、「い★こ」という結果を期待しているのですが出力がありません。 また、 strA="ぬ¥¥ね"; や strA='ぬ¥ね'; と指定しても同様にダメでした。 どなたか解決策をご存知でしたらご教授宜しくお願い致します。

    • ベストアンサー
    • Ruby
  • makedbm

    awk 'BEGIN { FS=":"; OFS="\t"; } \ /^[a-zA-Z0-9_}/ { print $1, $0 }' /etc/passwd | \ /ussr/etc/yp/makedbm - $YPDBDIR/'domainname'/passwd.byname $YPDBDIRはNISのデータベースディレクトリ これは/etc/passwdからpasswd.bynameマップを作るときのmakedbmの実行の仕方なんでsyがm awkコマンドがどういう動作をしているのかが、いまいち理解できないでおります。 入力フィールドの区切りを":",出力の区切りをスペースにしているんだと思いますが、 $1,$0は何を表しているのでしょうか。/^[a-zA-Z0-9_}/ は行頭が英数であるものを探しているんでしょうか。