トップページlinux
197コメント61KB

awk ファンクラブ

■ このスレッドは過去ログ倉庫に格納されています
0001login:Penguin2008/07/07(月) 20:45:18ID:wYmB5VwU
おーくについて語りましょう
0147login:Penguin2011/07/09(土) 07:11:28.80ID:OcQSMVqG
このスレ七夕に立ってたのか。3周年って言われると、まだ3年かと思ってしまう。
3年前といえばLLが盛り上がってた頃だから、もう少し前に立ってればここももっと盛り上がっていたかもね。
gawkは新しくなったけど、確実に他のLLに流れてるよなぁ…
0148login:Penguin2011/07/09(土) 07:34:21.50ID:OcQSMVqG
>>145
どこぞのOSでは使えない文字をわざわざファイル名に使わないよねって思い、楽してます。
ただパスに含まれる可能性はあるので、そういった場合は file -F; のようにして
fileコマンドの使うセパレータを(使われていない)任意の文字に設定して下さい。

スタイルに関しては全くその通りで、自分でも冗長だと思いつつ残しています。以下言い訳…

スペースは読み辛くなると思う所にだけ残すようにしています。また、ここに貼ると、
表示がプロポーショナルフォントになって、幅が狭い文字の隣から一部分コピペする操作をよくミスるため、
そういった幅の狭い文字(}とか;)の後には残しています。
ifやwhileの後、print $1 や "a" b "c" に含まれるものも省略できますが、違和感が物凄いので残しています。

セミコロンは(POSIXの仕様で)必要なものだけを残しているつもりです。
過去の互換性のために省略可能なものは、残すようにしています。
0149login:Penguin2011/07/09(土) 11:49:25.24ID:Ne909y4H
>>147
他のLLに比べて、Windowsで使われる頻度が滅法低いのも一因かなあと思う
コマンドプロンプトで awk がやれることって、BEGIN{ } に何か書くぐらいしか無いのよね
だったらPerlとかでいいじゃん、って話になっちゃう
0150login:Penguin2011/07/09(土) 15:37:05.06ID:Q3LPccup
awkオンリーってのがムズイので、Cygwin上でsh他外部コマンドと組み合わせて使う事が多い
0151login:Penguin2011/07/09(土) 17:09:11.40ID:Ne909y4H
結局awkはプログラミング言語というより「ちょっとややこしいことも出来るUnix系テキストツール」としての性格が強いんだと思う。
0152login:Penguin2011/07/09(土) 17:38:27.04ID:OcQSMVqG
そうか、Windowsでの使用率は考えたことなかったわ。そっちで今何が流行ってるのかは知らないけど、
GUI扱うライブラリを持つLLが使われてそうだ。こればかりは厳しい。そもそも、ライブラリって概念がないのが避けられてるのかな。
0153login:Penguin2011/07/09(土) 17:45:48.05ID:Ne909y4H
>>152
いやGUIはほとんどVisualStudio、Java、Delphi辺りで喰われてるよ
その他のGUIツールもあるにはあるんだけど

LLの主な出番は向こうでもテキストフィルタだったりはするんだけど
Windowsにはそもそも組み合わせるような小物のコマンド群が無いから
やりたい処理の1から10まで全部を1個(もしくは一連)のスクリプトで済ませるのが主流

だからたとえLLであっても、1言語で最初から最後までを完結できる大きめの言語が好まれるのよ
awkは単品で使うより、組み合わせで威力を発揮する言語だからか、あまり使われない
0154login:Penguin2011/07/09(土) 17:49:54.27ID:Ne909y4H
あ、いやテキストフィルタよりもCGIとかのWebでの出番のが多いか?
0155login:Penguin2011/07/09(土) 18:38:35.83ID:Q3LPccup
cgiでawk使う事って、珍しくないの?
0156login:Penguin2011/07/09(土) 18:59:11.34ID:wbKjo2Ly
awkでcgiも出来なくもないだろうけど、っていうかそれでblog作ろうとしてた人もいたな
0157login:Penguin2011/07/09(土) 19:07:48.49ID:OcQSMVqG
>>153
ホント?Delphiなんて懐かしいなぁ。GUIでなく、Webでの利用なら、もはやOSあまり関係ないような気も。よく分からん。

>>155
聞いたことはあるけど、見たことはない程度には珍しいかと。gawkはネットに対応してるから頑張ればサーバにもなれるかな?
0158login:Penguin2011/07/09(土) 19:58:21.74ID:Ne909y4H
>>157
いやまあDelphiは新規としては瀕死で、過去遺産の保守で使われるのが主だけどね。
0159login:Penguin2011/07/09(土) 20:14:45.59ID:Q3LPccup
やっぱawkでcgiってマイナーか。しかしblogつーか、CMS作ろうとするのは凄いなw

ちなみにgawkのhttpdって、どっかで見たなあ。
0160login:Penguin2011/07/09(土) 20:57:21.04ID:CG+O7ik7
httプロトコルでなく、俺プロトコル用サーバならawkスクリプトでやってる。
httpに例えるなら、ファイルか404を返すだけの簡単なやつ。
しかもgawkのソケットでなく、inetdから呼ばれるだけの低機能。
0161login:Penguin2011/07/10(日) 16:44:29.85ID:nBMv6TVB
私はエンバカになっても応援してるよ!>Delphi

>>160
今更inetdって思ってて、ろくに調べてなかったけど、socatみたいな機能もあるんだね。
ポート監視→サーバ起動って機能しかないと思ってたよ。

これならネット非対応なawkでもhttpdくらい実装できる?…バイナリまともに扱えそうなのはgawkしかねー。
テキストオンリーまでなら何とかできそうだけど、画像も転送できないか。厳しい制限だ。
0162login:Penguin2011/07/11(月) 00:10:26.11ID:ShNAK0f0
個人的にはawkは今まで通りシェルのお供でいいと思う
perlとかでもそりゃ書けんことは無いが
シェルのお供として使うには微妙に違和感あるんだよな〜
0163login:Penguin2011/07/14(木) 01:48:17.88ID:I04Pjvnw
>>134
これを使って正規表現によって grep とどれだけ実行速度に差が出るのか計ってみた。
ttp://pastebin.com/bpXZ5pg8

数字だけではよく分からないので、ユーザ時間のグラフを描いた。
ttp://i53.tinypic.com/303a4iv.jpg
赤がawk、青がgrep
こっちじゃないと見れないかも → ttp://tinypic.com/r/303a4iv/7

awk もばらつきがあるけど、grep ほどではない。
どちらも、マッチする可能性が高い正規表現は遅くなる傾向があるのかなぁ?
0164login:Penguin2011/07/14(木) 23:45:53.76ID:I04Pjvnw
引数で与えられたファイルをメモリに読み込み繰り返し検索する
awk 'BEGIN{f=ARGV[1];while((getline<f)>0)a[n++]=$0;close(f);ARGV=1};{for(i=0;i<n;++i)if(a[i]~$0)print a[i]}'

最近、用途が限られているもの中心だったので使えそうなワンライナーにしてみたよ。きっと。
指摘を受けたので、スペースは削ることにしました。ちっと見づらい?

↓は大文字小文字を無視するもの。こうするとdmesgの出力を何回も検索できる。
awk 'BEGIN{f=ARGV[1];while((getline<f)>0)l[n++]=tolower(a[+n]=$0);close(f);ARGC=1};{for(i=0;i<n;++i)if(l[i]~tolower($0))print a[i]}' <(dmesg)
0165login:Penguin2011/07/15(金) 08:26:42.31ID:ZNSgasJH
見にくいので、セミコロンで改行して欲しい。
0166login:Penguin2011/07/16(土) 01:01:45.88ID:bjjWiIZ6
凄く長くなりそう><
0167login:Penguin2011/07/16(土) 08:37:16.54ID:n6+rd2ar
長過ぎるone-linerを見易く改行するone-linerを書きなさい
0168login:Penguin2011/07/18(月) 15:25:02.07ID:7hj9vKr7
しまったー!書き込む前にちょろっと書き換えたところがバグってました。mawkで動きません。

>>164の下のスクリプトは次に書き換えてください。
awk 'BEGIN{f=ARGV[1];while((getline<f)>0)a[n++]=$0;close(f);ARGC=1};{for(i=0;i<n;++i)if(tolower(a[i])~tolower($0))print a[i]}'
awkのシーケンスポイントってC言語と同じなのかな…痛いミス。

おまけ。使ってるやつ。エスケープシーケンスを使って見つかった文字列に色を付けた。
awk 'BEGIN{f=ARGV[1];while((getline<f)>0)a[n++]=$0;close(f);ARGC=1};
    {for(i=j=0;i<n;++i)if(k=match(tolower(a[i]),tolower($0)))print C(j=!j)I(I(a[i],C(39),k+RLENGTH),C(31),k);print C()};
    function C(n){return"\033["n"m"};function I(x,y,z){return substr(x,1,z-1)y substr(x,z)}'
パターンごとに改行を入れた。少し見やすいか?

>>164の上のスクリプトに色を付ける機能を追加。ずっと分かりやすいと思う。
awk 'BEGIN{f=ARGV[1];while((getline<f)>0)a[n++]=$0;close(f);ARGC=1};
    {for(i=j=0;i<n;++i){l=a[i];if(sub($0,C(31)"&"C(39),l))print C(j=!j)l}print C()};
    function C(n){return"\033["n"m"}'
subをgsubにするとマッチする全ての文字列に色を付けられるよ。

gawkならgensub使ってもう少し短く書けるかもしれない。IGNORECASE=1で簡単に大文字小文字無視できるし。
0169login:Penguin2011/08/15(月) 19:41:00.75ID:yTTHvZyj
classは使えるようになりましたか? > gawk4
0170login:Penguin2011/08/16(火) 15:17:21.28ID:Tuhp+s5y
つ ttp://awk.info/?doc/dsl/awkplusplus.html
0171login:Penguin2011/08/16(火) 15:27:51.45ID:2FR0TK0E
ちゃんとご自分で読んだものを「つ」されてますか?
0172login:Penguin2011/08/21(日) 15:15:49.17ID:EL3rN3cw
ふるいけや "かわず とびこむ" みずのおと
といったレコードを、
field[1]=ふるいけや
field[2]=かわず とびこむ
field[3]=みずのおと
number_of_field = 3
とフィールド分割するすっりした方法を教えて下さい。
0173login:Penguin2011/08/21(日) 16:45:12.36ID:iSpKRH15
" で split すればいい
0174login:Penguin2011/08/21(日) 18:45:31.99ID:EL3rN3cw
やはり2chでは馬鹿レスしかつかんか。
0175login:Penguin2011/08/21(日) 18:56:18.08ID:Fst2eXVD
>>172
それ、CSVとかでもよく語られることだけど、意外と面倒なのよ。
例えば「"」自体を文字列に入れたい場合はどうするのか、とか色々決めなきゃならんし。
01761702011/08/21(日) 19:12:48.13ID:yoctsNv6
あれ?awkでclass使いたいって事なんでしょ?
ttp://ja.wikibooks.org/wiki/AWK%2B%2B%E3%81%AB%E3%82%88%E3%82%8B%E3%82%AA%E3%83%96%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%E6%8C%87%E5%90%91%E5%85%A5%E9%96%80
0177login:Penguin2011/08/21(日) 19:24:48.22ID:yoctsNv6
>172
素直に区切り文字を変えるしか...

ふるいけや,かわず とびこむ,みずのおと

FS=","
01781722011/08/21(日) 22:01:39.45ID:Mb9j323G
自己レスです。
BEGIN { FPAT = "([^" FS "]+)|(\"[^\"]+\")" }
みたいな事をしました。
0179login:Penguin2011/08/22(月) 10:27:15.81ID:bf5ta6rs
awk にわけわかんな機能を増やすよりも、
RFC4180 互換なフィールド分割オプションを実装すればいいのにといつも思う。
0180login:Penguin2011/08/22(月) 10:33:38.59ID:uwcmdhh8
馬鹿の巣窟にわざわざ書き込むな馬鹿
0181login:Penguin2011/08/22(月) 11:11:08.80ID:4smqF+KA
見事に馬鹿の巣窟と化したねえ
0182login:Penguin2011/11/28(月) 19:46:48.89ID:NIKBR+N1
perl -e 'print $1 if /href="(¥d¥d¥d¥d-¥d¥d¥-¥d¥d)"/'
と同じことをawkでやろうとしているのですがわかりません。
awk -e '/href="(¥d¥d¥d¥d-¥d¥d¥-¥d¥d)"/ { print ??? }'
グルーピングしたあとにそれを取り出す方法を探したのですが、わかりませんでした。
awkまたはsedでのやり方を教えて下さい。

0183login:Penguin2011/11/28(月) 20:46:46.52ID:skmC2JM9
>>181
馬鹿じゃないあなたに是非>>182の回答をしてもらおうか。
0184login:Penguin2011/11/28(月) 21:15:52.48ID:Oo5SGhpX
>>182
perl がわからないから求めるものがよくわからないけれど、こんな感じ?

awk '/href=\"[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]\"/ {print $1}' input.html

awk '/href=\"\([0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]\)\"/ {print $1}' input.html

BEGIN とか使ったほうがいいのかもしれないけれど
awk '/href=\"[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]\"/ {print $1} BEGIN { 何か書く }' input.html
0185login:Penguin2011/11/28(月) 23:48:15.14ID:mynsjW2o
>>182
どのawk使っているか分からないし、入力の仕様も分からないけど、どこでも動くのはこんな感じ
awk -F\" '/href=/ { for (i=1; i<=NF; i++) if ($i ~ /href=$/ && $(i+1) ~ /[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]/) print $++i }'
gawkでも正規表現パターンのグループを保存している組み込み変数はなかった気がする
0186login:Penguin2011/11/29(火) 00:49:47.68ID:6tCpTQmb
gawk4.0なら
awk '{if (match($0,"href=([0-9]{4}-[0-9][0-9]-[0-9][0-9])",a)) print a[1]}'
じゃ駄目?
0187login:Penguin2011/11/29(火) 01:04:03.02ID:6tCpTQmb
ごめん、
awk '{if (match($0,"href=\"([0-9]{4}-[0-9][0-9]-[0-9][0-9])\"",a)) print a[1]}'
0188login:Penguin2011/11/29(火) 16:01:19.31ID:vLvhB/JG
>>184-186
うーん、あまりわかりやすい方法ではないですね。
メンテナンスしにくいコードになってしまうので、perlが使えるよう上司に交渉したほうがよさそうです。
回答いただいた方、ありがとうございました。
0189login:Penguin2011/11/29(火) 16:28:12.31ID:MmS6Zrem
>>185はともかく>>186-187の方がPerlみたいにグローバル変数にマッチ結果を入れるより分かりやすいと思うのって俺だけ?
0190login:Penguin2011/11/29(火) 17:00:24.97ID:vLvhB/JG
>>189
186は、単にgawk独自の拡張機能を知ってないとわかりにくいというだけであり、
マッチした結果を明示的に変数に代入するのはいいことだと思います。
なお個人的には
match(string, rexp, matched)
はmatchedがいわゆるout変数になるため分かりにくいです。
matched = match(string, rexp)
のほうがよかったです。
0191login:Penguin2011/11/29(火) 17:27:04.96ID:8ESv/UnH
>>190
何言っているのかちょっと分からん。言語仕様上awkは配列を返せないだろ
0192login:Penguin2011/11/30(水) 00:16:56.92ID:CRejWMLU
gawk独自の実装はどうも…という話がよく出てくるけど、
gawk/mawk/true awk相互で運用する必要ってよくあるものなの?
またはbusyboxのawkで使いたいとか?
0193login:Penguin2011/11/30(水) 02:39:57.37ID:TGbwU425
gawkは最早awkと呼ぶには拡張され過ぎている感じがある
よくあるかは知らないけど、少なくとも手元の環境には3種類のawkがあって、gawkの拡張が使えない
mawkはnextfileにも対応してないし、awkは実装の差がかなり大きいと思うよ
0194login:Penguin2011/12/01(木) 00:38:55.88ID:cIbdY7f8
gawkが拡張されてるのは承知だが、gawk依存だとメンテが大変だから
perlというロジックが分かりにくい。

0195login:Penguin2011/12/03(土) 01:06:16.24ID:0aRpOAWF
gawkで

(ああ(いい((うう)(ええ))))

この行の「ああ」「いい」「うう」「ええ」を変数に入れたい時、
何か定番な書き方はありますか?
0196login:Penguin2011/12/03(土) 01:56:31.82ID:ivCb+cNz
何を期待しているのか分からん
括弧を区切りにして分けたいだけならFS="[()]+"で
配列に入れたいならsplitでどう?
0197login:Penguin2011/12/03(土) 01:59:50.51ID:ivCb+cNz
もしかして括弧の対応をとりながら分けたいってことなら
gawkに詳しい別の誰かに期待してくれ。拡張正規表現でも無理じゃなかったか
■ このスレッドは過去ログ倉庫に格納されています