awking shoes
オーク
オーク
オーク
奥さん
いや多くを語ってくれ
6 :
デフォルトの名無しさん:2007/02/25(日) 06:34:37
ローカル変数、。
7 :
デフォルトの名無しさん:2007/02/27(火) 21:39:18
クロージャを持ったawk実装とかないかね
8 :
デフォルトの名無しさん:2007/02/27(火) 23:45:59
コマンドプロンプトでちょちょっと使うことは頻繁にあるけど
気合い入れてプログラミングするってのは最近無くなった。
トッパンのプログラミング言語AWKがブックオフで105円で叩き売られてるのを見て
なんか悲しい気分になった
>>10 俺もオライリーの「sed & awk プログラミング」本が、図書館の「無料で持ってけー棚」
にあったので、即 GET した。まあ、かなり古い本(1991 年)だけど、内容はいい本だ。
定価 \3800 円のバカ高本で、 たぶん、新書では買わなかっただろう。
トッパンのプログラミング言語AWKって、いつごろの本だったけ。とりあえず、105円なら
欲しいっす。
>>11 赤い表紙の第1版だねきっと。
緑の表紙の第2版が手元にあるけど、gawkで拡張されている
正規表現の説明とか増えてて第2版のほうがお勧め。
ちなみに定価4100円なり。
13 :
11:2007/03/01(木) 23:52:54
>>12 > 赤い表紙の第1版だねきっと。
そう、それそれ。 ほんで、
gensub がない。もちろん、
/inet/..... |& .... もない。
最近、/inet/..... |& .... がある(gawk3.1 から)ことを知って、gawk を見直している。
使い捨てのプログラムは gawk に汁!!。
>>11 トッパンの最初の本なら確か1990年の春頃だったと思う。
一応nawkレベルの記述のはずなんで、gawkなんかの固有の
拡張を除けば十分使えるでしょ。
105円は…ちと悲しいけどいい人に拾われて欲しいねえ。
>>13 gawkの /inet 拡張ってイマイチ使いづらくね?
汎用的なのかもしれないけど、お手軽にhttp経由でwebページの
内容取れればいいってときに記述が面倒。
awkでSQLのleftjoinみたいなことできる?
20 :
15:2007/03/04(日) 03:46:24
エンコーディング対応とか色々考えると、awkでHTMLを処理しようとするほうが
無理がある感じ。
素直にPではじまる言語とか使っとけば?みたいな。
22 :
19:2007/03/04(日) 04:55:31
>>21 PとかR使えってのはまあそうなんだけど、HTMLの妥当性とかエンコーディングを気にしないで
いい使い道で考えてた(個人的にそういう需要がある)のでね。
HTMLに関してはきちんとしたドキュメントならxgawkでどうにかなる?
昔、Fortran、Cぐらいしか知らなかった時、
「えっ、こんな数行で計算出来るの?」
「プログラム内にファイル名書かなくて良いの?」
「この数行で、すべてのデータの計算してくれるの?」
って、驚きながら友人に教えてもらいました。
今なら、Excelでするような計算はすべてawkでしてました。
アスキーから256倍シリーズが出たぐらいだから
注目の言語だったんだよね。
Visicalcと1-2-3はawkブームより昔からあったんだけどね。
UNIXって意外と古くないんだよね。
>10
発行所が新紀元社の「プログラミング言語AWK」を2005年に定価3465円(税込)で買いました。
奥付に「本書は1989年11月に株式会社トッパンより発行されました。この度、株式会社新紀元社より、原出版社、訳者の許可を得て再発行いたしました。」と書かれています。
新紀元社ってRPGの本しか出してないと思ってたから意外だ。
大昔に通ってた高専の土木工学科にはawkの授業があった
実験のデータ処理にでも使ってほしかったんだろう
>24
awkブームは、西暦だと何年頃でしょうか?
>>28 DOS末期。256倍本が出た93年頃がピークでは。
後のPerlとは比較にならないプチブームだけど。
30 :
28:2007/04/17(火) 08:45:33
>29
御回答ありがとうございます。
鬼車awkを誰か作ってくれないかなー
あとローカル変数が欲しいな
functionの中はローカル変数になるよ。
いつから?未だに引数に並べるもんだと。
あー、ごめん、引数並べたやつがローカル変数になる。だった。
先に宣言すればいいんだから別によくね?
キモいやん。そのやり方。
39 :
デフォルトの名無しさん:2007/09/14(金) 04:37:24
これからawkを勉強します。
awkを学ぶことになるでしょう。
41 :
デフォルトの名無しさん:2007/09/15(土) 01:03:04
みなさんawkは語らないのですね。
船頭awkして船山に登る。
人に言えるほどawk知ってる訳でも無いし
だけど人の話は聞きたいし
awkぼ利通
1
47 :
デフォルトの名無しさん:2007/09/19(水) 16:41:49
awkを勉強しているのですが、Perlに慣れているからか
awkでできることはPerlでワンライナーでやったほうが(少なくとも自分にとっては)速い気がしてなりません。
これについてawk熟練者である皆様はいかがお考えになりますか?
こういう時はawkのほうが便利!という例にはどんなものがありますか?
48 :
デフォルトの名無しさん:2007/09/19(水) 16:43:11
↑あっ速いというのは、コードを書くのが速いという意味です。
>>47 perl はなくても awk なら入っている事がある
「コードを書くのが速い」という基準で、
「こういう時はawkのほうが便利」という例を他人に挙げさせても、
それはその人間にとっての速い気がする便利さであって、
意味のある一般的な議論にならないのではないか?
PerlもRubyもPythonも使うけど、特定のカラムだけに興味があるケースは
無意識にawkを使うこともある。
perl -a とか cutしてpasteとかもあるけど。
52 :
デフォルトの名無しさん:2007/09/19(水) 18:19:27
>>49 環境によらず入っているということですね。
>>50 そうですね。
なぜawkなのか、
一般的にはどういう時にawkが使われるのか、
というのがイマイチ自分のなかで分かっていないのです。
>>51 少し勉強した限りでは、確かにカラムの取り出しはawkが便利なのかもと思いました。
>>52 シェルスクリプトの中で、貧弱なシェルの計算能力を
補うために、ツールボックスの一つとして使われることが多い。
ので、シェルスクリプトを書く機会が多いのなら、やっておいて
損は無いと思うが、フットプリントが多少デカイこととやや移植性に
欠けることを気にしなければ、別にPerl使ったっていいわけだ
(どうせ今なら大抵は使えるだろうし、awkにしても一応Posix標準だが
色々変種がある)。
ま、単に便利なスクリプト言語が欲しいだけなら、今更awkをやる意味は
ほとんどないだろう。
フィールド分割だけならperl -aでawkの真似ができるしな。
54 :
デフォルトの名無しさん:2007/09/19(水) 20:06:52
>>53 丁寧なお返事ありがとうございます。
シェルの計算の補助ですか。
シェルスクリプトを書く機会は多少はあるので、多少は覚えておこうと思います。
awkとperl、処理速度はどっちが速いんだろ?
ってオマエが試せって言われそうだけどふと思ったんで書いてみた。
awkは処理系多いからなぁ
何の処理かにもよるだろうし
どちらも得意とする単純なテキストのフィルタリング処理なら、
I/O速度で制限されるのでどちらでも(或いはsedを持ち出しても)大して変わらないと思う。
awkの真骨頂は一行野郎にあると思う私は、こんなのをよく書き捨てる。
--
awk 'BEGIN {print 1+2*3-4;}'
ls -l /tmp|awk '$5>0'
ls -l |awk '{sum+=$5;} END{print sum;}'
PerlにたいするAwkの現実的メリットはメモリ消費が少ないことくらいで
これは今の計算機では微々たる問題だ。
ESRのArt of UNIX Programmingを立ち読みしたら
Awkがメモリ節約のために仕様を制限したことが
早期に競争力をなくした理由と論じていた。
バッドな言語設計の見本って感じで、ちと不愉快だった
>>57 俺も時々やる。
その時は便利!と思って.cshrcとかにalias登録するけどすぐに忘れて同じ内容を手打ちしてたりする
その挙句にこれは便利!と思って.cshrc開くと既に登録してあるという…
(.cshrcを.bashrcに置き換えて) 俺も同じ経験がある。
「一行野郎」は名訳
むかし、「読書するプログラマ」をよんで、awkで会計をするのがかっこ良いと
おもってました。
でも確定申告をする身になったらEXCELを使っている。
「エンジニアのための事務作業 sed awk grep そしてTex」なんて書籍があれば食いつくのに...
awkで会計用スクリプトを書くより、会計のしくみを理解することの方が
俺には遥かに難しい
Perl はコード一目見て俺がcore吐きそうになる
任意に core が吐けたら便利だよな。日記代わりになる。
>>67 体型維持のために余儀なくされている人もいたようです。
指を喉に入れるようにするので、俗に言うげろだこが指にできます。
69 :
デフォルトの名無しさん:2007/10/03(水) 23:18:59
awkってなんでPerl風に正規表現置換できるようにならんの。独自拡張でもいいんだけどな。
>>69 ん、くわしく。
Perlのメタ文字を使いたいというのとは違うの?
#使えんわけだが
awkはDFAでperlはNFAだっけか?
>>71 オリジナルではね。
中にはNFAを使っているawkもある。mawkとか。
73 :
デフォルトの名無しさん:2007/11/22(木) 06:36:33
xgawkで多倍長整数を使いたいんですが、
printf( "%ld\n", num );
では桁数は増えても精度は上がってないようです。
型宣言するにはどうするのでしょうか
>>73 多倍長整数を実装するのに個別の精度を上げてどうする。
>>76 「あなごる」の xgawk は MPFR 積んでないと思うが・・・。
そうですか
どちらにしても実数って事はやっぱ無理な気がしました
sedみたいに、パターン部分を行番号で指定出来ませんか?
>>79 awk 'NR == 79 {print;}'
ってこと? それとも、
awk 'FNR == 79 {print;}'
ってこと?
>80
はじめsedみたいに 10,35{ みたいな感じに書いてダメだったので; }
普通に比較式書くんですね。10<=NR&&NR<=35{ で出来ました; }
ありがとうございます。
>>81 もう少し sed らしくしたいなら、
10==NR, NR==35 { print }
なんてのもあり
awk はオプションなしだとワンライナーのコードを書くことになると思いますが
実際 awk のワンライナーってどんな時に使いますか?
あまり見たことがなくて…
>>83 UNIXでは多くのファイルや出力が欄区切りテキストの形式になっているから
その場使い捨てワンライナーが本来の使い方なんだけど、
他のOSだと BEGIN を main 代わりに使うようなのばっかになるかもね。
>>83がsedをどう使っているのか気になる。
sedスクリプトファイルとか作って、スクリプトの引数に処理対象のファイルを渡してたりするのかな。
よく書く一行野郎。
--
du -sk /tmp/* | awk '{sum += $1;} END {print sum / NR;}'
# まぁ、duってのは今思いついただけで、実際にduの出力の平均を取ることはないけどね。
--
paste foo bar | awk '($1 - $2) > 1e-3 || ($1 - $2) < -1e-3 {print NR, $0;}'
# 一致を見るだけならdiffでいいけど、近似を見るには使えないんで。
>>85 sedは単体の命令を見て「置換」「行の切り捨て」みたいな用途が
パッと見て思い付くので疑問は沸かないんです。
awkはひとつひとつの命令を見ても
普通にスクリプト言語の命令としか思えないので
「コード書くならともかく、ワンライナーでどう使うの?」と
疑問をもってしまうんです。
>>86 う~ん、結構複雑になりますね。
それだと私ならターミナルに書かずに
コードに起こしてしまいそうです。
でも、パターンとフィールドを上手く使えば
色々出来る気がしてきました。
例をありがとうございます。
あ、コード書きそうなのは後者です。
平均とか合計みたいなモノには良さそうですね。
今日書いた一行野郎。
--
awk '{for (ic = 1; ic <= NF; ++ic) {if (max < $ic) max = $ic;}} END {print max;}'
--
これも全フィールドに拡張しているだけで、単に最大値を得ているだけだね。
90 :
デフォルトの名無しさん:2008/01/22(火) 16:52:32
よく書く一行
du -k|awk '$1 > 10000'
でかいデレクトリをさがす
俺がよく書く一行野郎
$ awk 1 > hoge.sh
>>91 それに何の意味が?
cat > hoge.shでも事が足りそうだが。
>92
Windowsにawk入れてた時に、こんなヘンな癖が付いてしまった。
94 :
デフォルトの名無しさん:2008/02/02(土) 12:38:28
すみません、初心者ですがawkに関するスレがここしかなかったので。
↓のソースを書いていただいたのですが、いったいどうすれば使えるのでしょうか?
ちなみに、これはフォルダ内のWinrar形式ファイルのリカバリレコードが付いているか否か
リストを一括で出力するものです。
よろしこ
**************
コマンドラインだけどunrar lt sample.rarの出力利用してリストを作るだけ
使い方はパイプでawkに渡して処理unrar lt *.rar | gawk -f rr.awk
awkなんか入ってないだろうから当然そのままじゃ動かない
rr.awk
#!/usr/local/bin/gawk
BEGIN {$rr=0; printf "%-30s\t%s\n", "FileName", "RecoveryRecord";}
{if($1=="Solid" && $2=="archive"){
for(i=3;i<=NF;i++) printf "%-30s ",$i;printf "\t";getline;getline;
if($0=="Recovery record is present"){printf "Yes / ";
for(;;){getline;if($0=="Data header type: RR"){getline;printf "%sbyte\n",$2;break;}}
}else printf "No\n";}}
それを動かすにはまず gawk をどこかから入手する。
>>94 >↓のソースを書いていただいたのですが、
書いた人に聞く。
と答えると、わけのわからん理由を言ってごねるだろうから、
先に言っとくと、そんな見苦しい言い訳するな。
どうせ答えたって、今度は○○がわかりませんとか言い出すんだろ?
どっかからgawkを落として展開しろよ。全く、一生ググってろよカス
"C:\Program Files\WinRAR\UnRAR.exe" lt *.rar | "gawkのフルパス" -f rr.awk
すいません、あるテキストを{print $1,$2}として抽出して
aaa 1
aaa 2
aaa 3
bbb 1
bbb 2
ccc 1
ccc 4
...
とまではできたんですが、並んでいるデータをそれぞれ、
aaa 6
bbb 3
ccc 5
と集計したいんですが、どのようにすればいいでしょうか?
awk '{count[$1] += $2;} END{for (aaa in count) {print aaa count[aaa]}}'
あとはソートすればいいはず
99 :
97:2008/02/10(日) 20:22:03
>98さん、ありがとうございます!
情けないのですが、今まで便利なツールに頼っていて全然コマンドについて理解できていなかったので困っていました。
実はメールログで送信者がどれだけの通数を送信してるかを確かめるためにコマンドでできないか、で>97でつまづいていました。
何とか途中までできたんですが、非常にスーパーエレガントな1行コードでして…。
質問ついでで申し訳ないのですが、
(aaa in count) {print aaa count[aaa]}
のaaaについてはどう解釈すればいいのでしょうか?
>>99 bashとかのforとかと同じで適当な文字列ならなんでもいいです.例に出てきたaaaなんかにするからややこしくなってすみません.
for(hoge in list) {...}
で配列listのキーを片っ端からhogeに入れてループするって意味になるはずですよ.
98じゃないけど
awk '{count[$1] += $2;} END{for (i in count) {printf "%s %i\n", i, count[i]}}'
こうやって書けばしんせつじゃね?
データの中のaaaとloopカウンターのaaaを同じ名前にするのは意地悪だと思うよ
102 :
デフォルトの名無しさん:2008/02/10(日) 20:37:23
101です。すまんonz
103 :
≠98:2008/02/10(日) 20:39:44
あー、みんな書いているから私の書いたのは大幅に削るか。
そのENDブロック内は、
for (制御変数 in 連想配列) {...;}
というパターン。
その前段のcount[$1] += $2は一行目のとき
count["aaa"] += 1と解釈される。以下同様に。
このcountが連想配列として使われているということ。
>>101 …反省してます
いや,ほら,ついいつものクセで…ごめん
105 :
97:2008/02/10(日) 20:52:15
いえいえいえいえ…そういう意味じゃなくて教わっていながらすいませんです。
上記で書いたとおり便利ツールに頼り切ってて殆ど知らない私が悪いのですが…。
今一生懸命3byte程度の脳みそで勉強してるんですが、2日目で挫折しそうで質問させて貰いました…。
たとえばログには
Feb 9 22:44:40 localhost postfix/qmgr[1936]: 345C48C0154: from=<use1@example.com>, size=556, nrcpt=1 (queue active)
と必ず出ます。で、
1,生ログをそのまま処理するのが怖い(大きなファイル)ので、日付でログを抽出して別ファイルへ保存。
2,grepで nrcpt=と抽出して、さらにgrep -vで除外するドメインを指定して抽出
3,そしてsedでnrcpt=を削除して
4,ここで>97のように$7と$9を並べたところで脳みそのバッファエラーを起こしました。
この処理の方法もエレガントなことは分かっていますが、恥は承知でお伺いした次第です…。
gsubで[.*]を置き換えるにはどうすればいいでしょうか?
>>106 それはリテラルとして扱ってということかい?
なら全部エスケープすればいいと思うが何か問題があるの?
awkで現在時刻からn分前から以降のログだけを抜き出したいんですが、どうすればいいでしょうか…。
02 15 12:34:56 xxxxxxxxx
02 15 13:45:01 xxxxxxxxx
...
...
...
とかの形式なので、strftime()とかで現在とログの時刻を比較して抜き出す、とかを試したんですがダメでした…
>>108 これで駄目かな?(一応 gawk 3.0.4 では動いた)
BEGIN{
n=5
basetime=strftime("%m %d %H:%M:%S", systime()-60*n)
}
{
chktime=substr($0, 1, 14)
if(chktime >= basetime) print
}
>109
ありがとうございます…素直に目が鱗でした…。
> chktime=substr($0, 1, 14)
なんですね…
perlが使えない環境なので、これが分かればいろいろ流用効くので助かりました。
ありがとうございます。もうちょっと精進します。。。
>>29 昨年6月に「AWKを256倍使うための本」が本屋の書棚にあったので買いました。
奥付に
1993年8月21日初版発行
2007年5月9日 第1版第16刷発行
と書かれています。
>>111 いつのレスにレスしてんだ(w
モレも買ったけど、まだ大きな本屋で見かけるね。
>2007年5月9日 第1版第16刷発行
本屋の棚で眠り続けてたってわけじゃないのかw
目が鱗 に一致する日本語のページ 約 1,920 件中 1 - 20 件目 (0.24 秒)
メガ鱗
sed, awk, ruby を使う。
それぞれ適材適所で使うけど、
「sed だけ」「awk だけ」で済ませられると、
不思議な喜びを感じる。
117 :
デフォルトの名無しさん:2008/03/30(日) 14:05:33
>>116 うち、AIX使ってるんでksh+sed+awk+perlだな。
rubyが標準でインストールされてる環境ってあんまないと思う。
古いサーバだとPerlすら入ってない事があるからawkは重宝する。
最近のgawkがネットワークにも使えると知ってちょっと驚いたw
カーニハンの本レベル(とか256倍)しか知らない人って多いと思う。
120 :
デフォルトの名無しさん:2008/04/06(日) 12:44:41
ノーマルのawkでXMLを字下げしたりしてうまく表示させるにはどうすればいいのかな・・・
121 :
デフォルトの名無しさん:2008/04/06(日) 17:09:18
sedだけで書けると、俺って頭イイかもって思う。
#!/bin/sed -f
文字列の単純な置換だけならawkより簡単に書けるんだけど。
awkに固執しないで臨機応変にsedを使うって意味でなら要領がいいという意味で賢いけど。
# awkで書いた方が簡単なことをsedで頑張って書いたのだとしたら、その意味では頭悪いなw
awkからsystemでsed呼ぶことは時々あるw
>>24 awkって表計算のような処理に特化してますよね。
その点が非常にユニークというか事務処理の言語だな、と。
visicalc(1979)awk(1977)ですからawkのほうが若干古いんですが、
表計算はセルに直接式を書くという発想が新しかった。うむむ。
VisiCalcの考案者Dan Bricklinによるアイデアの説明
ttp://www.danbricklin.com/history/saiidea.htm Danの電卓がHPじゃなくてTIなのが意外な感じ。
The idea for the electronic spreadsheet came to me while I was a student at the Harvard Business School, working on my MBA degree, in the spring of 1978.
Sitting in Aldrich Hall, room 108, I would daydream.
"Imagine if my calculator had a ball in its back, like a mouse..." (I had seen a mouse previously, I think in a demonstration at a conference by Doug Engelbart, and maybe the Alto).
And "..imagine if I had a heads-up display, like in a fighter plane, where I could see the virtual image hanging in the air in front of me.
I could just move my mouse/keyboard calculator around, punch in a few numbers, circle them to get a sum, do some calculations, and answer '10% will be fine!'"
(10% was always the answer in those days when we couldn't do very complicated calculations...)
はじめましてgawkの質問です
お手すきの時にでもご解答頂けましたら助かります
2chでお話していただいた方からgawkを教えて頂きました
正規表現でマッチした部分がいくつあっても全ての箇所を1アクションで保存できる優れものです
当方、言語は全く知らないので先ほどまでテスト実行しては驚いていました
この優れものを今後末永く使っていきたいのですが
下記の事項をググって見たのですがわかりませんでした
どなたかわかる方おられましたら教えて下さい
私のやりたいこと
・EUCを読み込んでS-JISを出力
・既存のテキスト末尾に追加書き込み保存
(教えて頂いたスクリプトは上書き保存なので出力先の内容が消えてしまいます)
気長に待っていますので何卒よろしくお願い致します
>>126 前者はawkでやるべきことではない。iconv, nkfなどそれ専用のツールがある。
後者も必ずしもawkは不要。コマンドラインが使える環境なら普通にできる。
例えば、Unix系なら cat append.txt >> original.txt で既存のファイルに追加できる。
DOS系でも、type append.txt >> original.txt でできる。
要は、awkのいいところはそれ単体でなんでもできる(或いはできない)ことではなく、
コマンドライン環境で力を発揮するツールであること。
例えば、正規表現でマッチした文字列を置換するだけならテキストエディタでもできる。
あーそうそう、エディタがあれば文字コードの変換もそれだけでできる。
所謂テキストエディタを使ったことがないなら、一度(正規表現検索機能、
文字コード変換機能のある)テキストエディタを触ってみるといいかもしれない。
>>127さん
>>126です
お疲れのところ早々のご解答誠にありがとうございます
コンバートは別のツールで行う
DOS環境ではtype append.txt >> 出力先ファイル名で追加書き込み
了解しました
エディターは秀丸エディターを使っています
コンバートは出来るのですが検索でマッチした文字列は1箇所ずつコピーなんです
sakuraエディターで一括コピーや切り取りが出来ると教えてくれた方もいてたのですが
sakuraエディターは試したことが無いんです
詳しくありがとうございました
AAA.txtを開き”東京(.+?)号室”を検索する
マッチした複数箇所を一括でコピーしてTEST.txtにペーストする
BBB.txtを開き”東京(.+?)号室”を検索する
マッチした複数箇所を一括でコピーしてTEST.txtの末尾にペーストする
CCC.txtを開き”東京(.+?)号室”を検索する
マッチした複数箇所を一括でコピーしてTEST.txtの末尾にペーストする
よろしくお願いします
>>127は結局awkの解答はしないのになんでしゃしゃり出てきたの?
できないじゃん
>>130 質問に具体性がないから一般論を書いただけだけど。
>>129 awk '/東京(.+?)号室/ {print > "TEST.txt";}' AAA.txt
awk '/東京(.+?)号室/ {print >> "TEST.txt";}' BBB.txt
以下同様に。
>>131 レスありがと
gawk '/東京(.+?)号室/ {print > "TEST.txt";}' AAA.txt
gawk '/東京(.+?)号室/ {print >> "TEST.txt";}' BBB.txt
ファイル名、ディレクトリ名、またはボリューム ラベルの構文が間違っています。
gawk3.16では使えない?
>>132 DOSのコマンドラインの使い方は他所で聞いてくれ。
役所の窓口みたいな対応だな。
DOSのコマンドラインについては多くを知らないんだよ。
DOSの場合は空白を含む場合シングルクォートじゃダメだからな。
ダブルクォートで括って中のコードは
シングルクォートか、エスケープしてダブルクォート入れるか。
一番簡単なのは、ワンライナーでもファイルに起こしてしまうこと。
gawk -f myscript.awk AAA.txt
とやってしまえば、シングルクォートとかダブルクォートとか気にする必要はない。
>>132 二つ問題がある。
gawkの正規表現では.+?というのは使えない。
cmd.exeでは、シングルクォートを引数を
くくるのに使えない。
なんかよくわからんが、perlでテキストを丸飲みしてから
処理すればいいんじゃないのか?
VisiCalc といえば、出始めの頃に TRS-80 用 を Radio Shack で見せてもらったんだけど、学生だった私には価値がわからなかったなぁ。
まぁ、これに限らず、『なんでこんなコマンドやオプションがあるんだ?』ってのは多い。
使い方じゃなく、なぜそれがあるのかを包括的に解説した本や web site ってありますか。(たとえば多くの unix コマンドを網羅しているとか)
ああ、スレ違いだった。ごめんごめん。
なんという誤爆
>>132 もう居ないかな。gawk3.1.6 + nkf2.0 使用@cmd.exe
C:\work>type aaa.txt (※EUCなので化ける事を確認)
、ロ、イ、ロ、イ
ナ・�ケ貍シ
ナ・�」イケ貍シ
ナ・�」ア」ーケ貍シ
ナ・�、ロ、イケ貍シ
ナ・�、ユ、ャケ・ナ・ユ、ャケ貍シ
ナ・�」ウケ貍シ、ネナ・�」オケ貍シ
C:\work>nkf -Es AAA.txt
ほげほげ
東京号室
東京2号室
東京10号室
東京ほげ号室
東京ふが号
東ふが号室
東京3号室と東京5号室
C:\work>nkf -Es AAA.txt| gawk "/東京.*号室/{print $0}"
東京号室
東京2号室
東京10号室
東京ほげ号室
東京3号室と東京5号室
既出の通り文字変換nkf(
>>127) 正規表現の制約で条件変更(
>>137)
実際に使う場合はこんな感じでバッチ作るとか。
C:\work>nkf -Es AAA.txt| gawk "/東京.*号室/{print $0}" >>TEST.txt
142 :
141:2008/05/06(火) 02:56:02
と、方法を書いておいてアレだけど、
秀丸使ってるならgrepの実行で検索するファイルに(現在の内容)で
検索結果からファイル名と行番号を除去するのでもできそうな気がする。
盛大にスレ違いだけど。
>>142さん
ありがと
まだ思うようにできていないんだ
参考になるよ感謝です
ひでえwwwwwwwwwwwwww
すまん誤爆
146 :
デフォルトの名無しさん:2008/06/25(水) 02:17:58
質問です!
以下のファイルhogeからawkで、価格を抜き出して合計値を出したいと思っています。
ファイルの内容は、書籍名と価格です。価格は一番後ろの数字になります。
----------------------
$ cat hoge
それいけ!あんぱんまん 1000
メタボリックを撃退せよ 1000
下流社会 1000
上流社会と下流社会 日本のこれから 1000
論文 2008 日本の抱える問題 1000
論文 2007 日本の抱える問題 過去問題集 1000
----------------------
難しいのが、書籍名の2008や2007などの数値が含まれていることや空白が含まれていることです。
1行目の場合2列目が価格になりますが、2行目の場合4列目が価格となります。
このように一番最後の列(価格)を取得し、合計値を計算するにはどうすればよいでしょうか?
ご教示お願いいたします。
awk '{x+=$NF}END{print x}' hoge
xじゃなくてsumとかにしようよ。
一行野郎は手数(打数)重視なんじゃまいか
難しいってマニュアル読めば最後の要素を指すものが何か書いてあると思うが
読んでたら他人になんか聞きません。
じゃあ、マニュアル読んでもわからなかったらお手上げか
Windows 版の gawk-3.1.5 で`双方向パイプがうまく動作しません。以下、
http://www.kt.rim.or.jp/~kbk/gawk-3.1/gawk.html#SEC182 からのサンプルファイルですが、途中で止まってしまって、返事が返ってきません。
BEGIN {
command = "sort"
n = split("abcdefghijklmnopqrstuvwxyz", a, "")
for (i = n; i > 0; i--)
print a[i] |& command
close(command, "to")
while ((command |& getline line) > 0)
print "got", line
close(command)
}
Cygwin の gawk では問題ありませんでした。
どうやったら Cygwin の gawk(GNU Awk 3.1.6) で print length("あいう") が 3 になるのですか?
Windowsのバージョンくらい書こうな。でないと釣りと思われるよ
jgawk?
gawk.dllって、まだ誰かメンテしてくださってるんでしょうか?
最新版gawkのdllを探してるんですが、見つかりません。
または、ソースのtar.gzからdllを作る方法が載っているページを
御存知の方がいらっしゃいましたら、教えていただけると助かります。
なにをいってるのかわからん
ソースのtar.gzってなに?
http://ftp.gnu.org/gnu/gawk/ からダウンロードできるgawk-*.tar.gzのことですが。。
sourceからgawk.exeを作ったりしないのですか??
dllと書いているのでわかるかとは思いますが、
windows環境下での話です。普段はcygwinでmakeしたgawkを使っているのですが、
dllがあると他の言語から呼び出して使えるので便利かなーと思ってます。
cygwinはwin用のソースじゃないから
win用のソースがいる
>>160 昔あったDLL版は作者が独自に作ったものみたいで
本家に反映されてないから本家のソースからDLLを作るのは無理。
DLL版のソースを参考にして自力で作るか
できないなら作者に連絡して協力を求めるしかない。
(ノ∀`) アイタタタ
165 :
155:2008/07/05(土) 15:47:31
>156
XP [Version 5.1.2600] でつ
>>153 まだ見てるか?
多分なおってると思うんで新しいので試してみてくりや。
うお?
作者降臨か
すんばらすぃ
AWK 使って15年? 30年前のコードが吐き出すデータをちょこっと処理しようとして…
FS=/[ ()]+/ は期待通りの動きをせず、FS="[ ()]+" と書かねばならない。
初めて知った。
検索しても、これについて明快に書いてあるページがなかなか見つからなかったが
>正規表現定数がそれ自身として現れたとき、それはパターン中に現れたかのように、
>つまり`($0 ~ /foo/)' のようにみなされる。
<中略>
>言語のこの機能は、POSIX標準までドキュメント化されなかった。
orz
これで1時間ぐらいムダにした。私が知らなかっただけですか??
『プログラミング言語AWK』には一応載ってるけどな
> (FSに代入される)文字列が1文字より長いときは,正規表現として扱われる
ベル研系統の言語は記述の自由度はあるが挙動がつかみづらい
>>170 ””で囲んだ文字列が正規表現として扱われる ということと
//で囲んだ正規表現定数で書いてはいけない ということは同じではない。
実際、split関数の 第3引数に与える正規表現は どちらでも動く
むむむ、ここでは($0~/foo/)に置き換えて評価されないんだ…
171の意見が正しいようだね チャンチャン
173 :
デフォルトの名無しさん:2008/07/21(月) 12:39:44
複数のファイルの読み込みってできますか?
print ファイル1の$2 ファイル2の$1
みたいな感じで
>>173 pasteで繋いじゃダメ?
私はよくやるけど。
仮にファイル1が5カラム固定なら、
paste ファイル1 ファイル2| awk '{print $2 $6;}'
てな感じで。
# カラム数可変ならもう一捻り必要だけどね。
>>173 awkだけでやりたいならgetlineを使えばできる。
awkすごい便利で、gnuplotと組み合わせてExcelから解放されつつあります。
上の方にあったDFAとNFA使ってる事からくる違いってなんですか?
>>176 一番の違いは、DFAだと後方参照ができないことかな。
とりあえず
DFA
前準備に手間を掛けるけど処理そのものは早い
NFA
即座に処理を始めるけど、処理に時間がかかる場合がある。
ぐらいに考えておけばいいと思う。
保守
sh + awk は明らかに簡単だと思う。
sh + awk で出来ることを perl のみで記述する人の気持ちがどうしても理解出来ない。
ただ、ネットワークプログラミング以上になるとC, perl, ruby にならざるを得ないけど。
マシン単体での種々の手続き記述だと、
sh + awk がやっぱり一番完結になると思うんだけどな~。
おれもawkでできることならawkでやる。
でもあまりにトリッキーなことになりそうだったらperlでやったりするかな。
人に渡す可能性があるなら、awkは結構つらいことがある。
Perlでやれば基本的に問題ないから、Perlで書く癖がつく。
ShellScriptでいったん使うだけなら、awkは便利だけど。
>>180 俺も AWK でできるならAWK。
と考えると バイナリーのデータいじる以外はAWKでできるのでは…
(少なくとも 俺に日常のニーヅでは そうだ)
>>182 同感。ただバイナリは仕方ないにしても、
全半角混在の固定長フォーマットが扱いにくいんだよな。
ASCIIにすると全角のみ部分が処理しにくいし、
SJISとかにすると正しく切り出せないし・・・
あれはなんとかならんものかな。
やっぱり ASCII だけの問題にしておいた方が無難。
>>185 いや、そのgawk使ってるけど、全半角混在の固定長は困るはず。
両方別々なら問題なく扱えるけど、同時には扱えない。
例えば。SJIS1行5バイト+改行の固定長ファイルで
1行は2項目(a:全半角混在4バイト b:半角のみ1バイト)のファイルがあるとき。
asciiモードならa, bを切り分けられるがaの全角文字は処理できない。
sjisモードならa, bを切り分けられない。
悩ましいのは、項目を切り分けるスクリプトをascii オプションで起動して
出力結果をsjisで処理すれば(めんどくさいけど)現状で処理できてしまう。
ので、マニュアルに書いてある通り、作者をおねがいすれば可能性はあるかもしれないが、
お願いするのが躊躇われる感じなのね。
awkは時代の関数だから使われなくなっていくんだろなあ
UTF-8の場合でも固定長は半角幅しか対応できてない。
文字数とバイト数と表示幅とか、日本語は面倒だのう。
length()とかでバイト数を拾えないから自前で処理もやりにくい。
>>188 一瞬納得しかけたけど。
冷静に考えると、そもそも1文字が可変長であるUTF8を
固定長ファイルの文字コードに使おうと考えた奴を締め上げて
泣くほど問い詰める方が先だと思うのは俺だけ?
考えても考えてもメリットが思いつかないよ…
>>189 ほとんどの文字コードが可変長だからなあ。
相対的に見ればマシな方に入るんじゃない?
ホストが絡むと文字コード周りは悲惨だよ…
ホストじゃないならそもそも固定長じゃなくて良いんだけどね。
あるフィルタスクリプトをgawkで書いているのですが
文字のコードを整数値に変換しようとしてうまくいきません
たとえば「c」という文字のコードを整数値にしようとして
BEGIN {
testChar = "c";
printf("testChar=%d\n",testChar);
}
のようにしても「testChar=0」と表示されてしまいます
良い方法があればお教えください
>>191 awklib に ord ってユーザー定義のライブラリ関数があるからそれを使う。
自前で作ってもいいけどね。
くわしくは info gawk で調べて。
193 :
191:2008/08/23(土) 03:28:08
>>192 ありがとうございます
早速検討してみます
194 :
191:2008/08/23(土) 10:56:41
入力内容をawkで生成することは出来ますでしょうか
もしくはBEGIN等のブロック内で文字列を生成して
その文字列のパターン毎に分岐、フィールドを使っての処理
(要はawkに入力ファイル渡した時に簡単に書ける処理)
を簡単に書くことは出来るのでしょうか
例えば…どんな処理が適切な説明か判りませんが
BEGIN{for(i=0;i<10;i++) print int(rand()*10),int(rand()*10),int(rand()*10)}
の結果に対して
$1+$2+$3<10{ print $1+$2+$3 }
$1+$2+$3>=10{ print ($1+$2+$3) % 10 }
…とかそんな感じで、テキストを生成した結果に対して
フィルターとして比較式や正規表現で分岐して、フィールドを使って処理する感じです。
やっぱりバッチファイルとawkファイルをいくつも作ったり
一行一行に対してif文で分岐したりsplitで分割するしか無いですかね…。
>>195 敢えて入力を生成したいのなら、awkをパイプで繋げばいいと思う。
そうではなく、単に乱数で処理を振り分けたいのなら普通にif文でいいと思う。
それはさておき、
--
$1+$2+$3<10{ print $1+$2+$3 }
$1+$2+$3>=10{ print ($1+$2+$3) % 10 }
--
は別に上の条件式は要らんだろ。一桁の数値を10で割った余りは元のままだからな。
>196
いやあくまで例題なので内容は深く考えないでください…orz
普通にif文とは言うものの、折角awkが標準で備えてる便利な機能を無視して冗長な書き方するのも難だし
かと言って.awkファイル複数個とバッチで、パイプでつなげて処理するのも…う~ん、となってしまう。
良い書き方無いかなぁと思ったので聞いてみたのですが、ifとsplitで頑張ります。
質問がよくわからんのだが、BEGIN部で生成したファイルを処理部で扱いたいということかな?
例えば、
gawk 'BEGIN{ ARGV[1]="in_file.txt"; ARGC=2; }{ print }'
ってやったら in_file.txt を表示できるぞい
>198
!!!
目から鱗です。
そっか、ファイル生成しちゃえば一発で行けるのか…やってみます
うげ、一旦ファイルを作るのはありなのかよ。
ifを使うのは冗長なのに、ファイルを作るのは冗長じゃないってどんなセンスなんだ。
>200
入力データは規則性のあるもので、生成してしまえるけど
それに対しての分岐は多い…という場合
ifやsplitを羅列するよりも、awkが元々持ってる
パターンとフィールド分割を使った方が
スッキリすると思うのですが間違ってるでしょうか…。
>>201 別にいいんじゃね?
巨大な中間ファイルを作るってわけでもないんだろうし。
まぁ、次の理由で私は中間ファイルを作るのは避けるけどね。
・フルパスを指定しない場合、カレントディレクトリに書き込み権限がある保障がない。
・そもそも同名ファイルが存在していて書き込み権限がないかも知れない。
・つーか、同時に2件動かしたらバッティングしてしまう。
・だからと言って、一々ユニークな名前のファイル名を生成するのも面倒だ。
・しかも、中間ファイルは後で消しておく必要があるかもしれない。
それと、自前で入力を生成するなら、最初から分割された状態で作ればいいからsplitは要らないね。
パターンを使うかifを使うかは趣味の問題のような気がするけど。
# $1+$2+$3<10{print;}と書くかif($1+$2+$3<10){print;}と書くかの違いだもんね。
色々考え方があるのね。
自分ならトリッキーな細工して1つに収めず分割してif使わずに書くけど。
手早くカタをつけられるのがawkの良い所だと思うし、
技巧に走ると間違いなく忘れるのでメンテ不可能になる可能性大
ま、それはそれとして
>>198はパズル的な面白さがあって良いね。
>202
う~ん、言われてみればそうかも。
一応、今回のは仕事で使うわけでもなければ他人に使ってもらう予定もない
完全な個人用スクリプトなのでどうにでもなりますが
これが業務や自分以外も使うものであれば素直にifなんでしょうね。
2008/09/15 13:17 61 20080915142145.txt
2008/09/16 13:17 316 2008091611529.txt
2008/09/22 20:09 24,028 2008_0922asahiindex.txt
2008/09/22 12:57 1,545 clean.txt
というファイル一覧から、gawkで今日の日付のファイルだけ抜き出すにはどうすりゃいいんだっけ?
BEGIN{month = strftime("%m",systime()); date = strftime("%d",systime())}
/month/ && /date/ {print $0}
でいいかと思ったら、/ /のなかにmonthとかは使えないらしい。
/strftime("%d",systime())/ {print $0}
とべた書きしてもだめ。
ど忘れ中。ヘルプミー。
BEGIN{date=strftime("%m/%d")} $0 ~ date {print $0}
質問です。
入力中のファイル名はFILENAMEにセットされますが、
入力中のファイルのパスを取得するにはどうしたらよいですか。
>>208 FILENAMEで得られる情報が全て。フルパスが欲しいということなら、
cwdを取得してそこからの相対パスがFILENAME。
210 :
デフォルトの名無しさん:2008/11/12(水) 19:19:08
awkの結果を set か setenv の変数に代入したいです。
awk '{ print $1+ $3 }' test.txt
で数値が出ます。
この結果を変数に代入するにはどうしたらいいんでしょうか?
set tmp=`awk '{ $1+ $3 }' test.txt`
これだと上手くいきません。print はそのままでいいのでしょうか?
なんで print を省略できると考えたのかが謎だが
>print はそのままでいいのでしょうか?
まず試せよw
新紀元社のプログラミング言語awkがどこも売り切れなんだけど
もう入らないのかな
>>211 printは画面表示するもの→変数に入れるだけなら不要
…と思ったんじゃ内科ね
カンマ区切りのデータファイルがあり、その中で、第1フィールドと第3フィールド内にもし
子音、子音、子音、母音が存在すればその行だけ抜き出すオークのスクリプトファイルをつくりたいのですがどうすればよいですか
>>215 データファイルのサンプルと抜き出したい行ヨロ
こんな感じです
takeshi,fiad,fdjioaf,fdjsoafds(←該当なし)
dddacea,fsaofsa,rrra,fjisaofdjsa(dddaとrrraが該当)
aexxxu,dsoifsa,yyyuo,fjsaofa(xxxuとyyyuが該当)
オークスクリプトを実行すると情報を表示するようにしたのですが1行目と最後の行だけを表示しないようにするには
END内に何て書けば宜しいでしょうか
>>215 BEGIN{FS=","}
function term_check(term, lower_term) # lower_term は局所変数
{
lower_term=tolower(term)
if(lower_term ~ /[bcdfghjklmnpqrstvwxyz][bcdfghjklmnpqrstvwxyz][bcdfghjklmnpqrstvwxyz][aiueo]/) return 1
return 0
}
{
if(term_check($1) && term_check($3)) print
}
パターン繰り返しって {3} とかでいけるはずなんだが
書き方知らないのでコピペしたw
>>218 逐次出力してる?
END でまとめて出力してる?
>>218 1行ずつバッファリングして、次の行の入力で前の行を出力すれば最後の行は消えてなくなる。
awk 'NR > 2 {print buffer;} NR > 1 {buffer = $0;}'
>>215 gawkなら
awk -F "," -v r="[bcdfghj-np-tv-z]{3}[aiueo]" --posix '$1 ~ r && $3 ~ r'
$1と$3どちらか一方にあればいいなら&&を||に変えてね
出来ました ありがとうございます
込み入ってて整理できないので教えてください。
・対象のテキストは2行目がない(1行目しかない)かつ
・1行目はひらがなカタカナ漢字で15文字以内
という条件を書くのって、次のようにしたのですが、うまくヒットしません。
どう書けばいいでしょう?
NR==2 && length($0) == 0 && NR==1 && /[ぁ-んァ-ヶ亜-腕]{1,15}/
>>225 NR == 2 && NR == 1じゃ、絶対成立しないだろ。
awkは行を1行ずつ処理するから、事前にトータル行数を知ることはできない。
トータル行数が1行であることを保証したいなら、ENDブロックで処理するしかない。
>事前にトータル行数を知ることはできない
BEGIN部で数えれば?
>>228 どうやって? 対象がファイルである保証があるならwcでも呼べばいいけどそれならawkでやる必要さえないよね。
{ a = $0 }
END { if (NR == 1 && a ~ /re/) print a }
とか?
どなたか、任意ビット幅の2の補数HEXをDECに変換するプログラムを書いてもらえませぬか?
仕様が不明確なところがあるし、なによりなんでawkで?
「あなたは何故awkでやろうとするのですか?」
「そこにawkがあるから」
awkからsystem()でgrepとかsedとか呼んだりする癖が付いている
シェルスクリプトにする方がむしろ違和感
おいおい、grepやsedぐらい呼び出さずにawkでやろうぜ。
grepやsedはパイプでつなげて使うものじゃないの?(^^;
239 :
デフォルトの名無しさん:2009/01/10(土) 22:10:41
gawk 3.1.4 mb のwindows版のEXEファイルが欲しい…
なんでそんな古いバージョンが欲しいの?
241 :
デフォルトの名無しさん:2009/01/11(日) 12:16:04
>なんでそんな古いバージョンが欲しいの?
lengthとかsubstrで、「j」付き文字列関数があるからです。
3.1.5以降だと、同じスクリプトファイル内で、バイト単位処理と
キャラクター単位処理の混在が難儀なのです。
242 :
240:2009/01/11(日) 15:01:36
3.1.5で文字の扱いが変わったのはその通りだけど、3.1.4のWindows版て
jlengthやらあったっけ?
なかったと思うんだけど。
243 :
デフォルトの名無しさん:2009/01/11(日) 15:48:22
>なかったと思うんだけど。
えっ。3.1.4以前のはバイト単位オンリーって事ですか?
…それでも2バイト換算で扱えばいいから、まだマシかも。
j付きが追加されていたけど、動作変更に伴って廃止された…
と思っていました。
記憶にあるのは、どなたかの独自拡張別Verだったのか…?
244 :
240:2009/01/11(日) 17:54:21
> えっ。3.1.4以前のはバイト単位オンリーって事ですか? ちゃう。
jなんとかがあったのは、
2.11ベースのjgawkと2.15ベースのjgawk
2.15ベースのとgawk+mb
3.0.xベースのgawk+mb
で、3.1.xベースのにはなかったという話だったと思う。
それぞれやってる人が違う。
245 :
デフォルトの名無しさん:2009/01/11(日) 19:05:17
>3.1.xベースのにはなかったという話だったと思う。
そうですか…。
gawk 3.1.4 mb のwindows版のEXEファイルが欲しい…
ではなくて、
3.0.xベースのgawk+mb のwindows版のEXEファイルが欲しい…
という事になる訳ですが…無理っぽい。
あっても関数や組込変数が減少…その前に16bitDOS版ONLYの予感…。
諦めます。240さん、どうもでした。
247 :
デフォルトの名無しさん:2009/01/11(日) 22:30:39
>あるよ。3.0.6のやつ。
おお。 ありがとうございます。
>3.0.6→3.1.xで増えた機能でも使ってんの?
いつ何が増えたのかよく把握していないんですが、
gensubとかmktimeとかswitch-caseとか…ありますかね。
まあ、代替手段はあるので試してみます。どうもです。
248 :
デフォルトの名無しさん:2009/02/23(月) 08:11:12
awkで、組み合わせの全てを作る、という事はできるのでしょうか?
いわゆるnCrの、個数ではなくて、中身を知りたいという事なのですが・・・。
(mawkを使っています)
250 :
sage:2009/03/04(水) 15:23:19
248です。
なんとかできました。249さんどうもです。
sage間違えた…
int(0.5005*10000)が5004になるのはなぜですか。
丸め誤差でしょう。
切り捨て前に0.5足すとか工夫してみては如何でしょうか。
詳しくは、IEEEと丸め誤差辺りのキーワードで検索のこと。
>253
ありがとう
255 :
デフォルトの名無しさん:2009/04/13(月) 21:36:16
gawkで掲示板作りたいんですけど、
gawkが使える無料鯖どこかにありませんか?
Linuxが入ってるレンタル鯖なら入ってるんじゃないかなぁ?
レンタル鯖板できいてみたら。
さくらのFreeBSDはFreeBSDのawk(!=gawk)だった。
>>256 さくらはgawkですか。
Windowsじゃないレンタル鯖ならawkが使えても良さそうですけど、
無料ではなかなか見つからないんですよね。
perl,ruby,phpは多いんですけどねぇ。。
258 :
257:2009/04/13(月) 22:14:30
失礼。
さくらはgawkじゃないawkですか。
>>259 同じくウケた
awkは永続的に使っていて,C-->C++-->Javaと乗り継いできたが,awkはこれらコンパイラ言語を使う上で
良い学習材料になってきたと思い感謝している(もちろん未だにscriptのawkをawkで書いている).
唯一awkで勉強できなかったのがOOPだったから,学習材料としてのawkがこういう方向に活路を見いだすのは
良いことかもしれない.ただし実用に向けて考えてみると,個人的にはOOPが本領を発揮するのは頭の中でalgorithmを
把握しきれなくなる程度に大きなシステムを組み上げる場合なので,果たしてそれをawkで書くかといわれると….
261 :
260:2009/04/18(土) 13:57:19
s/algorithm/データ構造/
262 :
デフォルトの名無しさん:2009/05/09(土) 23:49:39
最近rubyの勉強始めたんだが、
「rubyがあればAWKいらね」とは思えん。
逆にAWKの便利さを再認識した。
やっぱり、簡単なテキスト処理は
AWKでやったほうが簡単だ。
各行に対して処理って場合はawkが良いね
rubyはオブジェクト指向を強制されるから小回りがきかん
265 :
デフォルトの名無しさん:2009/05/10(日) 01:20:35
266 :
デフォルトの名無しさん:2009/05/14(木) 08:38:05
jawkの話題が全然出ないね。
使ってる人少ないの?
>>266 さくっと1行で済むのが気に入ってる俺には無用だな
{if(miso<$1){printf($1)}} miso=30
を実行すると$1が1桁の数字のときにうまくいかないんですけどなぜ?
文字列で比較されてるんじゃね?
miso<$1-0
でやったらどう?
>>271 ありがとうございます。でもだめでした。
文字列で比較されてるっぽいですね。
>>270 何を入力したときに何が出て欲しいの?
うまくいかないってどうなるの?
>>273 $1が4のときに出てほしくないのに出てしまうんです...
>>274 こんなん?
BEGIN{miso=30}{if(miso<$1){printf("%d\n",$1)}}
>>275 出てしまう理由が気になります...なんででしょう
やっぱり271さんの言うとおり文字列比較してるんでしょうか?
>>276 awk のバージョン(種別)が分からない
何を食わせてるのか分からない
スクリプトは一行で書いてるのかファイルにしてるのか分からない
一行で書いているならシェルに何を使っているのか
文字列比較されてるなら一桁のときに上手くいかないというより
二桁のときだけ上手くいくという感じなのかね。
WindowsXPのコマンドプロンプトでgawk(3.1.5)使って下記を試してみたけど
その現象再現できなかった。
gawk "{if(miso<$1){printf($1)}}" miso=30
$awk -W version
mawk 1.3.3 Nov 1996, Copyright (C) Michael D. Brennan
compiled limits:
max NF 32767
sprintf buffer 2040
$seq 1 40 | awk '{if(miso<$1)printf($1)}' miso=30
31323334353637383940
うまく動いているようだが。
>>279をマネさせてもらった
$ awk -W version
GNU Awk 3.1.6
Copyright (C) 1989, 1991-2007 Free Software Foundation.
$ seq 1 40 | awk '{if(miso<$1)printf($1)}' miso=30
31323334353637383940
miso=30って-v付けなくていけるんだ。しらんかった。
gawkは
コマンドラインで指定されたファイル名が var=val という形式ならば、それは変数への代入であると解釈されます。変数 var は値 val に設定されます (これは、すべての BEGIN ブロックを実行したあとに行われます)。
やっぱりもれの XPコマンドプロンプト環境でも
>gawk -W version
GNU Awk 3.1.6
Copyright (C) 1989, 1991-2007 Free Software Foundation.
>seq 1 40 | gawk "{if(miso<$1) print}" miso=30
31
32
33
34
35
36
37
38
39
40
って期待通りの動きだYO!
固定長で改行なしのファイル(6MB超)を処理することになり、
他のソフトで「改行ありの固定長」にしてから、awkで処理していたのですが…
データファイルによく出てくる文字をとりあえずRSに見立てて読み込み
→RSに指定した文字を連接
→固定長の1行分より長かったらその部分を切り出し
していくと「改行ありの固定長」、できちゃいました。
RSに指定した文字がしばらく出てこなければ変数パンクしちゃうし、大分危なっかしいの
ですが、とりあえずawkでできたのが少しうれしい。
改行ありの固定長をawkで読んだのなら
substr($0, start, length) でばらせよw
>>283 >284みたいな読解力ない馬鹿が湧かないように、判り易く書きましょう。
つーか、具体的なコードも出さずに「awkでできてうれしい」なんてのはチラシの裏にどうぞ。
fold とか?
正規表現で空白で区切られたテキストをHTMLでいうtableにしたいです。
例)
10進 2進 8進
000 000 000
001 001 001
002 010 002
003 011 003
↓↓↓↓↓↓↓
<table>
<tr><th>10進</th> <th>2進</th> <th>8進</th></tr>
<tr><td>000</td> <td>000</td> <td>000</td></tr>
<tr><td>001</td> <td>001</td> <td>001</td></tr>
<tr><td>002</td> <td>010</td> <td>002</td></tr>
<tr><td>003</td> <td>011</td> <td>003</td></tr>
</table>
>>287 正規表現を使うほどのことではない
コアの部分だけ書くとこれだけ
for(i=1;i<=NF;i++) printf("<td>%s</td>", $i)
正規表現使ってタグを切り替えたいのかな?
split や asort したらどうして添字が1からになるんだ!
なんでだ!
仕様書読み飛ばしててデータ欠落させるところだった(´・ω・`)
>>287 sed でええやん
それはそこのサイトの人に言えよ
いつのまにかgawk 3.1.7が出てた。
Ruby 勉強中だけど AWK のほうが楽しいぜ(´・ω・`)
7月7日→[[7月7日|07月07日]]
7月28日→[[7月28日|07月28日]]
11月3日→[[11月3日|11月3日]]
12月16日→[[12月16日|12月16日]]
と置き換えたいです。
perlならわりと簡単なのですが、awkで簡単にいきますか?
自分がawkのことを勉強不足だからかもしれませんけど…。
↑間違いました。
7月7日→[[7月7日|07月07日]]
7月28日→[[7月28日|07月28日]]
11月3日→[[11月3日|11月03日]]
12月16日→[[12月16日|12月16日]]
例がよくわからないんだけど,数字1桁の部分を2桁にしたいってこと?
{
gsub(/月|日/," ");
printf("%02d月%02d日\n",$1,$2);
}
とか.
フィールドセパレータがデフォルト(半角スペース)の場合ね.
>296
Perlで簡単に書けるなら、一旦Perlコード晒してくれるか?
どうも仕様がよく解らんのだ…
print gensub(/0([0-9])([0-9])/, "\\1\\2", "g", gensub(/([0-9]+)/, "0\\1", "g",
$1))
我ながら汚ねぇなぁ(´・ω・`)
>>299の方がいいな
>>298,300 置換しないで変えたいとこだけ出力するならこういう意味です。
#!/usr/bin/perl
while(1){
$line = <STDIN>;
if($line =~ /(0?[1-9]|1[0-2])月(0?[1-9]|[1-2][0-9]|3[01])日/){
$month = $1; $day = $2;
if($month >= 10) {
if($day >=10){
print "$& -> [[$month月$day日]]";
}
else {
print "$& -> [[$month月$day日|$month月0$day]]";
}
}
else{
if($day >=10){
print "$& -> [[$month月$day日|0$month月$day]]";
}
else{
print "$& -> [[$month月$day日|0$month月0$day]]";
}
}
}
}
1月1日 - ユーロ導入10周年。
1月1日 -> [[1月1日|01月01]]
12月31日 - ニューヨークのマンハッタン橋開通100周年。
12月31日 -> [[12月31日]]
8月21日 - ハワイ州州制50周年。
8月21日 -> [[8月21日|08月21]]
10月1日 - パラオ独立15周年。
10月1日 -> [[10月1日|10月01]]
なんか素直にPerlでやったほうが楽そうだなあ、それ。
ちなみに、そのコードじゃ無限ループするぞ。
#!/usr/bin/perl
while($line = <STDIN>) {
if($line =~ /(0?[1-9]|1[0-2])月(0?[1-9]|[1-2][0-9]|3[01])日/) {
$month = $1; $day = $2;
if($month < 10 || $day < 10) {
printf "%s -> [[%d月%d日|%02d月%02d]]\n", $&, $month, $day, $month, $day;
}
else {
print "$& -> [[$month月$day日]]\n";
}
}
}
だめだ…コードの意味は分かるが,仕様が良く分からん.
7月7日
という文字列を
[[7月7日|07月07日]]
と置き換える、ってことでしょ。
なんで分からんかなぁ。そっちのが分からん。
入力が07月07日だったら,
出力は[[07月07日|07月07日]]になるよね?これはOK?
そもそも,そういう入力は起こりえないの?
# gawk による match 関数の拡張を使っている.
# 一行に複数回現れた場合は無視.
BEGIN {
F = "(0?[1-9]|1[0-2])月(0?[1-9]|[1-2][0-9]|3[01])日";
}
{
if ($0 ~ F) {
match($0, F, a);
if (a[1]+0 < 10 || a[2]+0 < 10) {
sub(a[0], sprintf("[[%d月%d日|%02d月%02d日]]", $0, a[2], a[1], a[2], a[1]));
} else {
sub(a[0], sprintf("[[%d月%d日]]", $0, a[2], a[1]));
}
}
print $0;
}
310 :
309:2009/08/06(木) 21:21:15
# 訂正.
BEGIN {
F = "(0?[1-9]|1[0-2])月(0?[1-9]|[1-2][0-9]|3[01])日";
}
{
if ($0 ~ F) {
match($0, F, a);
if (a[1]+0 < 10 || a[2]+0 < 10) {
sub(a[0], sprintf("[[%d月%d日|%02d月%02d日]]", a[1], a[2], a[1], a[2]));
} else {
sub(a[0], sprintf("[[%d月%d日]]", a[1], a[2]));
}
}
print $0;
}
>>310 完璧です。今度からこれを使います有難うございました。
$ cat test.txt
1月1日 #m月d日
01月1日 #0m月d日
1月01日 #m月0d日
01月01日 #0m月0d日
2月10日 #m月dd日
02月10日 #0m月dd日
11月3日 #mm月d日
11月03日 #mm月0d日
12月16日 #mm月dd日
$ awk -f test.awk test.txt
[[1月1日|01月01日]] #m月d日
[[1月1日|01月01日]] #0m月d日
[[1月1日|01月01日]] #m月0d日
[[1月1日|01月01日]] #0m月0d日
[[2月10日|02月10日]] #m月dd日
[[2月10日|02月10日]] #0m月dd日
[[11月3日|11月03日]] #mm月d日
[[11月3日|11月03日]] #mm月0d日
[[12月16日]] #mm月dd日
最初にそういうテストバターンを出そうね
ここの住人がコーディング好きだからって甘えやがって(´・ω・`)
> perlならわりと簡単なのですが、awkで簡単にいきますか?
って言ってるんだから、「いきます」って答えりゃいいんだよな
バターン テストのデスマーチ
318 :
デフォルトの名無しさん:2009/10/24(土) 17:23:04
最後の10行を処理したくない場合、どう書けば良いでしょうか?
最後まで読まずに最後の10行かどうか判定する方法は無いだろうな
処理対象がファイルなら、事前にwc -lか何かで行数調べて awk に渡してみては
成る程、これ、という方法は無さそうですね
ちょっと考えながらやってみます
とりあえず、こんな感じにしました
BEGIN {
SKIPTAILS = 10
}
{
line = buf[1]
for(i=1;i<SKIPTAILS;i++) buf[i] = buf[i+1]
buf[SKIPTAILS] = $0
}
NR > SKIPTAILS {
# lineを処理
}
>>321 考え方は同じだけど、forが気になったので
リングバッファで処理するようにしてみた。
BEGIN {
SKIPTAILS = 10
ringpos = SKIPTAILS
}
{
ringpos = (ringpos + 1) % SKIPTAILS
line = buf[ringpos]
buf[ringpos] = $0
}
NR > SKIPTAILS {
# lineを処理
}
ありがとうございます
リングバッファ、勉強になりました
使わせて頂きます
質問です
gawkで
{
printf("%d,%s\n", NR, $0 ) > FILENAME;
}
という行頭に番号を振って保存する処理をして
batファイルで一括処理させようとしたんですが
c:\windows\gawk\gawk -f g:\作業用\n.awk g:\作業用\*.txt
実行結果が
ファイル1 ファイル2
1A 4D
2B 5E
3C 6F
になります
ファイル2も
1D
2E
3F
にするにはどうしたらよいでしょうか?
FNR
>>326 おお、出来た!
迅速な回答ありがとうございます
328 :
デフォルトの名無しさん:2009/12/21(月) 13:53:34
年末にパソコンを買い換えようと思って機種選びをしていてふと気づいた、
あれ、vaioのOSがWindows7 64bitバージョンに・・・
ダメじゃん!gawkが使えなくなってしまう・・・
うーん、、、またXPを買うべきか・・・悩む・・・
>>328 自分でコンパイルし直せばいいだけじゃないの?
AAA BBB CCC … -O ZZZ YYY XXX …
awk新参です。
-O(オプション)を検索し、
-Oとそれ以降をリダイレクトしたいのですが…
良い方法、ありますでしょうか
リダイレクトってどういう意味で使ってる?
その AAA で始まる文字列も一体どういうものなの。
コマンドライン引数なのか、ファイルから読み込んでくるのとか。
用語と状況はきちんと書いてくれ。
D:\My Documents\gawk\331>type 331.txt
AAA BBB CCC … -O ZZZ YYY XXX 0…
AAA BBB CCC … -O ZZZ YYY XXX 1…
AAA BBB CCC … -O ZZZ YYY XXX 2…
D:\My Documents\gawk\331>type 331.awk
{match($0, " -O .*", a);
print a[0];}
D:\My Documents\gawk\331>gawk -f 331.awk 331.txt >a.txt
D:\My Documents\gawk\331>type a.txt
-O ZZZ YYY XXX 0…
-O ZZZ YYY XXX 1…
-O ZZZ YYY XXX 2…
D:\My Documents\gawk\331>
334 :
331:2010/02/28(日) 18:43:32
レスありがとうございます。
>>332すみません。書き直します。
AAA BBB CCC … -O ZZZ YYY XXX …
と書複数行書かれたファイルがあり、
「-O」以降の文字列を別ファイルに保存する
ってことをしたかったのです。
>>333 エスパーな文だったのにありがとうございます。
想定してたのはそんな感じです。
ただ以下のエラーが出て上手くいきません…
gawk: 331.awk:2: fatal: match() cannot have 3 arguments
match使ってるのにaという3つ目の引数を使ってるから…ってことでしょうか…?
Q: make spits out errors like Makefile.awk:256: fatal: match() cannot have 3 arguments
A: Your AWK is too old to recreate the Makefile. The build is done based on the distributed Makefile. Everything shall compile successfully though.
So if the compile succeeds just ignore such errors, please.
336 :
335:2010/02/28(日) 19:22:38
{print substr($0, match($0, " -O .*")+1);}
337 :
331:2010/02/28(日) 20:03:12
>>336 出来ました。まさか本日中に解決できるとは思いませんでした。
ありがとうございます。大変勉強になりました。
ボソ 本当に勉強になったかどうかは疑問だ・・・
おっと一言オウかったか。
gsub()とかで引数に変数を利用したいのですがどうすればいいのでしょうか?
gsub(str1,str2)みたいに。
>>339 man gawkより
gsub(r, s [, t])
For each substring matching the regular expression r in the string t,
substitute the string s, and return the number of substitutions.
If t is not supplied, use $0. An & in the replacement text is
replaced with the text that was actually matched. Use \& to get a
literal &. (This must be typed as "\\&"; see GAWK: Effective AWK
Programming for a fuller discussion of the rules for &'s and
backslashes in the replacement text of sub(), gsub(), and gen sub().)
awk 'BEGIN{x="ABCDE";y="BCD";z="XXX";gsub(y,z,x);print x}'
何が難しいのかよくわからん。
342 :
デフォルトの名無しさん:2010/03/17(水) 22:07:37
時々awkだと遅いのでperlに書き換えるという人がいますが、
実際のところ速くなるんでしょうか?
私の環境ではforループや加算などはawkのほうが速そうですが、
どのような処理の場合にperlのほうが速くなりますか?
$ time mawk 'BEGIN{x=0;for(i=1;i<=1000000;i++){x=x+i};printf("%f\n" ,x)}'
500000500000.000000
real 0m0.131s
user 0m0.120s
sys 0m0.000s
$ time gawk 'BEGIN{x=0;for(i=1;i<=1000000;i++){x=x+i};print x}'
500000500000
real 0m0.289s
user 0m0.284s
sys 0m0.000s
$ time perl -e '$x=0;for($i=1;$i<=1000000;$i++){$x=$x+$i};print $x'
500000500000
real 0m0.379s
user 0m0.376s
sys 0m0.004s
>>342 「awkだと遅いのでperlに書き換えるという人」 に聞けば分かる
>>342 遅いというawkはgawkなの?
素のawkよりgawkの方が早くなかったっけ?
カーニハンとパイクの『プログラミング作法』にawkとperl
(とCとC++とJAVA)の比較があるな
今のマシン使って書き換えなきゃならないほど遅いって
どんな処理なんだろう?
>342
awk 等を組み合わせて実行するとプロセス起動のコストがかかるので perl で一つに纏める、という話じゃないの?
347 :
デフォルトの名無しさん:2010/03/22(月) 17:35:11
文字コードのコードを変数にして文字列を操作することってできますか?
文字列中の全角文字を半角文字に変える華麗な方法を模索しています。
Use iconv.
> 文字コードのコードを変数にして文字列を操作することってできますか?
なにをしたいのかよくわかんないんだけど。
> 文字列中の全角文字を半角文字に変える華麗な方法を模索しています。
華麗なのはtrコマンドを使う方法。ただtrがマルチバイトをうまく扱ってくれるか
どうかはこころもとない。
Perlならtrを、Rubyなら文字列クラスのtrメソッドを、
Pythonならstringモジュールのmaketrans関数と文字列のメソッドtransleteを使う、
という手がある。
awkないし(tr以外の)古典的なツールで華麗にやる方法はないと思う。
350 :
デフォルトの名無しさん:2010/03/24(水) 17:11:16
Excelで
全角半角変換は ASC()
半角全角変換は JIS()
>>347 1. EUC-JPにして(nkfとか)kakasi で、戻す
2. それだったら最初から、nkf -Z
3. gawk前提で、文字毎に処理(LANGを指定して子プロセス起動)
awkの中で閉じてやるのはめんどくさそう
gawk 3.1.6
system(cmd) を使うと、アンチウィルスソフト(kaspersky)の
アプリケーション履歴にバッチファイルが登録されるのを発見。
close(cmd) しても同じ。
while(cmd|getline>0){}
で代用すると残らなくなった。??
355 :
デフォルトの名無しさん:2010/05/14(金) 13:38:24
awkのprintについてご教示下さい。
下のような出力が有った場合、例えば
lrwxrwxrwx 1 root root 70 May 18 10:37 hoge
ls -al | awk '{print$1$2$2$4$6$7$8$9}' とすれば「$5」の
「70」を抜くことが出来ますが、これが$100とかまで続く場合、
「$5」だけを抜きたい場合記述が大変になります。
何か良い方法は無いものでしょうか?
$nに代入があると、その時点で$0が再構成される。
区切りの空白が$5のあったところだけ2個になるのが気にならなければ、
ls -al | awk '{$5 = ""; print}'
とすればよい。
空白2個を修正するならこうする。
ls -al | awk '{$5 = ""; print $0}' | awk '{$1 = $1; print}'
$0 は余計だった。
ls -al | awk '{$5 = ""; print}' | awk '{$1 = $1; print}'
2つめのawkの$1 = $1は何のため?
なにもしないと、$0は読み込んだそのままなので空白2個は空白2個のまま。
$1=$1で代入してやると、$1, $2, ...を空白1個でつないだものが$0に代入されるので、
空白2個だったところが空白1個になる。
2つめのawkに食わせた時点で$n (n>0)は詰まるけど$0は入力行そのまま
空白2個なので$0を再構成すると空白1個区切りになる
>>357-358 非常に解りやすいご説明、ありがとうございます。
なるほど代入することで解決するんですね。
勉強になりました。
$1 = $1 ってイマイチよく解らん
$1ってFSで区切られた一つ目だよね?
なんでそれ自身を自分に代入したらスペースが消えるん?
$0の再構成が行われるからって説明されてるだろ。
$0の再構成とはいったんばらした$1,$2,...をOFSを挟んで
つなげ直すってことなので、何で区切られていたかは
保存されない。
>>364 >$1=$1で代入してやると、$1, $2, ...を空白1個でつないだものが$0に代入される
って約束事を覚えておけってことかい?
ちょっと気になって試してみた。
% echo a b | gawk '{OFS="-";$1=$1;OFS="=";print}'
a=b
再構成は$1=$1をやってすぐじゃなくて、次に$0が使われるとき、ってこと
なのかな?
367 :
365:2010/05/18(火) 16:27:59
awkは奧が深いのぉ
久しぶりにいいもんを見させてもらいますた><
知らなかった。
勉強になった。
みんな>357のお蔭で多くを学んだな。
372 :
デフォルトの名無しさん:2010/05/29(土) 04:53:07
名前:
E-mail:
内容:
cygwinだと
% cut -f1 -d, hoge.csv
より
% awk -F, '{print $1}' hoge.csv
の方が速かった。
#実行時間ね
#Perl?シラネ
>>372 sed -e 's/,.*//'でもawkと同じくらいだから、cutの実装が遅いんだね。
cutが無駄にオプション多い所為じゃない?
手元のlinux環境だとcutの方が速いという普通の結果でしたが。
hoge.csvは6桁の乱数3つを「,]で区切って並べた100万行の
ファイルです。
% time cut -f1 -d, hoge.csv >/dev/null
cut -f1 -d, hoge.csv > /dev/null 0.21s user 0.01s system 99% cpu 0.222 total
% time awk -F, '{print $1}' hoge.csv >/dev/nulll
awk -F, '{print $1}' hoge.csv > /dev/nulll 1.52s user 0.03s system 99% cpu 1.558 total
ちなみにバージョンは
cut (GNU coreutils) 8.5
GNU Awk 3.1.7
あーなるほど、なんか判った。cygwinのfgetc()が遅いからじゃないかな。
fgetc()とfgets()で時間を較べたときにfgetc()の方がずっと遅かった記憶がある。
xgawk (gawkでなく)にとあるwebページを食べさせると、XMLERRR (not well-formed)で中断します。
そのページがwell-formedか極悪かは私にとってどうでもよく、単に内容を得たいだけなので、文末まで処理し終えて欲しいのです。
どうにかならないでしょうか。
シェルスクリプト内でパイプ入力されたものを処理する
アクションをヒアドキュメントで書く事は出来るでしょうか。
質問です。
データが
|1|aaa|
|2|bbb|
|3|ccc|
などとなっているとき
aaa
bbb
ccc
を取り出そうとして
awk 'FS="|"{print $3}' ファイル名
としたんですが、1行目だけがうまくとれません。
データファイルの1行目を空行にすれば解決できないことはないんですが、
空行を入れ忘れてしまう懸念があります。
どうすればいいんでしょうか?
やりたいことは awk 'BEGIN {FS="|"} {print $3}' じゃないかと思うんだけど
378です。
>>379 どうもありがとうございました。
382 :
381:2010/09/27(月) 19:00:47
>>381 マニュアルには1から9までって書いてあるし
Within the replacement text s, the sequence \n, where n is a digit from 1 to 9, may be
used to indicate just the text that matched the n'th parenthesized subexpression.
ソースの該当箇所(builtin.cの2542行目あたりから)みても1桁限定のロジックだよ。(3.1.7調べ)
int dig = scan[1] - '0';
なんてやってる。
一旦ぶった切るしかないんじゃね
385 :
381:2010/09/27(月) 19:12:31
>>383 どうもありがとうございます。
>>384 ちょっと見栄え悪くなるけどそうする(´・ω・`)
>>381 なんでそこのひとは16までできたんだ?
10の代わりに:を使っていたりして。
このスレが盛況なのが珍しいから
記念パピコ。
15年以上前だけどawkの勉強始めて同時にperlの勉強もしてたら
気付いたらperlばっかりやっててawkすっかり忘れてしまったなぁ
今はperl捨てて専らpythonやってるけどawkもいいよね
Busyboxに組み込めば、それこそ炊飯器や冷蔵庫でも動くからなあ。
手軽であるにも関わらず、結構高度な処理もガリガリ書けるから好き。
Cとシェルスクリプトが好きだから、文法的にもしっくり来る。
上位互換のPerlも大好き。
>>376ですが、誰もかまってくれないので寂しさで死にそうです。
>>391 どれでも好きなのを選べ
1. xgawkを改造
2. エラーになるXMLを事前に修正してwell-formedにしてから食わせる
3. xgawkは捨てて別の言語、ライブラリを試す
jawkがjwalkに見えてしまう
動く環境の多さ順にインタプリタを選ぶんなら、
シェルスクリプト > awk >>> perl >>>>> python >>>>> ruby >>> haskel etc.
となるだろうな。
シェルスクリプトはシェル依存な部分が多く、perl ほど高機能なものも要らない。
そんな時、小さな端末でもスマートに動いてくれる awk にちんこ勃つ。
>>389 言語に捨てるも拾うもないよ。その時々に都合の良いものを組み合わせて使うのがUNIX的な発想。
awk最近勉強してる。perlより全然簡単。
これなら俺でも挫折しなくてすみそう
sjisで書いた
/ー/{print}
を実行すると
awk:
awk: ^ 正規表現が終端されていません。
awk: 致命的: [ または [^ が対応しません。: /[/{print}/
のエラーになってしまいます。
ーの2バイト目が[なせいだと思いますが、どう対応したらいいでしょうか?
入力ファイルはsjisで書かれていて、文字コード変換はできません。
>>398 環境の問題なんだから、実行環境くらいまともに書けよ。
環境はCentOS-5.5-x86_64でGNU Awk 3.1.5です。
/bin/awkはシンボリックリンクで、実体はgawkでした。
Windows7(64bit)で使えるawkありますか?
32bit版のawkをを使うんじゃダメ?
405 :
398:2010/10/22(金) 07:32:34
こうすることで対応できました。
/\x81\[/{print}
それでいいなら、/ー[]/でもいい希ガス。
根本的な解決になってないけどねぇ。
シングルクオーテーションやダブルクオーテーションの使い分けじゃね~
408 :
398:2010/10/22(金) 19:55:53
根本的な解決するとしたら文字コードを変えることでしょうか?
日本語の文字コードに対応してるawkを使う、という方法もある。
今あるのかどうか知らないけど。
今のgawkは普通にUnicode対応してるみたい
$ echo 'てすと' | gawk '/[ぁ-ん]/ { print length($0) }'
3
UTF-8ロケールでしか試してないけど
cygwinでも大丈夫
412 :
399:2010/10/23(土) 06:55:10
413 :
398:2010/10/23(土) 10:53:14
サーバ管理者じゃないのでサーバをいじることはできないです。
これにしたらsjisでも動くようになるのでしょうか?
>>413 少なくとも自分が試したWindows2003上ではな。
▽tes.awk ※sjis
/ー/{print}
△
CentOS5.5上
$ gawk -f tes.awk readme.ja
awk: tes.awk:1:
awk: tes.awk:1: ^ 正規表現が終端されていません。
awk: tes.awk:1: 致命的: [ または [^ が対応しません。: /[/{print}/
Windows2003上
> gawk -f tes.awk readme.ja
⇒マッチした物が表示される
Linux上でロケールをsjis.japaneseとかにすればいいのかと思ったが、ロケール変更自体がうまくいかなかったわ。
困ってる事があるなら、最終的に何がしたいか言ったほうがいいよ。
415 :
398:2010/10/23(土) 12:40:31
Windows2003だとちゃんと動くんですね。
困っていたことは405で解決したので大丈夫です。
今は「根本的な解決」に興味があったのでお聞きした次第です。
416 :
初心者:2010/11/04(木) 22:14:10
awkでシェルのPATH変数をマッチさせるときにスラッシュ//を使わない方法を教えていただけませんか?
>>416 初心者だからマルチが許されるとでも思ったか?
418 :
初心者:2010/11/05(金) 06:32:09
ごめんなさい!
知りませんでした。
配列の要素数を調べるなら、ループ処理しないと分からない?
length みたいなのは無い?
あるよ。まさしく、length(array)。
そんなもんねぇよw
と思ったらgawkにはあるのか
length([s]) Returns the length of the string s, or the
length of $0 if s is not supplied. Starting
with version 3.1.5, as a non-standard exten-
sion, with an array argument, length() returns
the number of elements in the array.
むしろ配列が存在するってことはその配列を作成する過程があるだろ?
作成するときに数えればいいんじゃね?
連想配列だったら数えないのが普通だがな
424 :
419:2010/12/25(土) 03:12:23
function で処理する時、配列だけではダメで要素数まで必要なんだかなぁ、
って事が分かりますた
425 :
デフォルトの名無しさん:2010/12/28(火) 11:29:35
function に渡すだけなら要素数なんていらないんじゃない?
426 :
デフォルトの名無しさん:2010/12/28(火) 13:55:13
$1 = $1みたいなトリックを見る度に奥が深いと言うよりは糞に見えてきます
翻すとUNIX文化そのものが
まあ、あくまでおれの主観ですがね
>>426 awk大好きなオイラに喧嘩売るのかw
ウニックス文化最高!(NT系はUNIXのパクリ)
>>427 全角英字使う奴が awk 大好きだとは到底思えん
まあ冬休み期間だものね。
▼tes09.awk
BEGIN{
if (ARGV[1]=="")
ARGV[1]="hoge.txt"
while (getline < ARGV[1] > 0) print "BEGIN\t"$0
}
ARGV[1]=="hoge.txt"{
print "BODY\t"$0
}
★質問
上記スクリプトを引数を付けた場合と付けない場合をそれぞれ実行しました。
▼gawk -f tes09.awk hoge.txt
BEGIN arima_yuuichi@example.com
BEGIN ooizumi_sadawo@example.com
BEGIN taguchi_kenji@example.com
BODY arima_yuuichi@example.com
BODY ooizumi_sadawo@example.com
BODY taguchi_kenji@example.com
▼gawk -f tes09.awk
BEGIN arima_yuuichi@example.com
BEGIN ooizumi_sadawo@example.com
BEGIN taguchi_kenji@example.com
ここで、BEGIN句での ARGV[1]="hoge.txt" という代入を本編(?)でも有効にする為
にはどうすればいいでしょうか?
なにもしなくても有効だと思うんだけど
質問の趣旨がわからん
432 :
430:2011/01/06(木) 06:20:53
分かり辛くてすみません。
hoge.txtの中身は下記です。
▼
arima_yuuichi@example.com
ooizumi_sadawo@example.com
taguchi_kenji@example.com
>>430はWin32のバイナリ「GNU Awk 3.1.7(windows special Nov 24 2009)」を使用した結果です。
下のほうの実行結果では、BEGIN句でのARGV[1]への代入はBEGIN句では有効ですが、
本編では有効になっていないので出力されていないように見えます。
ちなみに、CentOS5.5上の GNU Awk 3.1.5 では下記エラーになりました。
▼
gawk: tes09.awk:2: if (ARGV[1]=="")
gawk: tes09.awk:2: ^ 表現の char '・' は不正です。
入力レコードが1件も無いからでしょ
>gawk: tes09.awk:2: ^ 表現の char '・' は不正です。
これは全角スペース
>BEGIN arima_yuuichi@example.com
>BEGIN ooizumi_sadawo@example.com
>BEGIN taguchi_kenji@example.com
コレはgetlineで読んで出力したもの
>BODY arima_yuuichi@example.com
>BODY ooizumi_sadawo@example.com
>BODY taguchi_kenji@example.com
コレはコマンドで指定したファイルから出力したもの
たとえば
{
print "BODY\t"$0
}
としてやれば明らか
435 :
デフォルトの名無しさん:2011/01/06(木) 13:46:53
質問の趣旨は、プログラム(スクリプト)の中で入力ファイル等の
コマンドライン引数を追加したいという事ですか。
コマンドライン引数の配列は ARGV ですが、コマンドライン引数の
個数を格納する ARGC という組み込み変数があります。
ARGV配列を追加したら一緒に ARGC を修正してあげないと、awkは配列が
追加された事を認識しません。
BEGIN内でARGV配列を追加した分だけARGCをインクルメントしてあげれば
追加されたARGV配列で指定されたファイルも本文の処理に渡されます。
蛇足としては、
現在処理中のファイル名が格納されている配列 ARGV のインデックスを
示す組み込み変数は ARGIND です。
私のは Win版の gawkm115 です。スクリプト内でARGV/ARGCを操作しても
期待通り正常に動きますよ。
試してみてね。
436 :
430:2011/01/06(木) 23:56:01
皆様レスありがとうございます。
>>433 >これは全角スペース
お恥ずかしい限りです(汗) 出勤前に思いつきで試したもので、スレ用に書いた
物をそのままコピってました・・・
>>434 BEGIN句のgetlineではARGV[1]への代入ができているのに、本文では有効に
ならないという事を伝えたかったのです。
437 :
430:2011/01/06(木) 23:56:17
>>435 自分の質問を見直してみると全く質問になっていなかったにも関わらずエスパー
してくださってありがとうございます。
ARGCについて理解できました。
BEGIN{
ARGV[1]="hoge.txt"
ARGC=2
}
ARGV[1]=="hoge.txt"{
print "BODY\t"$0
}
こんな感じで意図した通りに出力されました。
おかげさまで今までawkの補助としてshを使ってましたが、awkだけで書ける事が
多くなりました。
引数にワイルドカードを指定して、ARGIND で特定パターンのファイル名の
物のみ処理をするとかできそうですね。
質問です。
My Documents\2011\01\09(日)
というようにフォルダを切っていて、今日にcdするために、
today.bat
gawk -f today.awk > tmp.bat
tmp.bat
del tmp.bat
today.awk
BEGIN{year = strftime("%Y",systime()+9*60*60);
month = strftime("%m",systime()+9*60*60);
date = strftime("%d",systime()+9*60*60);
day = strftime("%a",systime()+9*60*60);
gsub(/(Sun)/, "(日)", day);
gsub(/(Mon)/, "(月)", day);
gsub(/(Tue)/, "(火)", day);
gsub(/(Wed)/, "(水)", day);
gsub(/(Thu)/, "(木)", day);
gsub(/(Fri)/, "(金)", day);
gsub(/(Sat)/, "(土)", day);
print "cd \"My Documents\" year "\" month "\" date day
}
というように処理しています。
これって、ひょっとして、gawkの内部からprintせずに実行することは可能でしょうか?
system関数で出来るんでは?winは分からないけど
system("cd \"My Documents\" year "\" month "\" date day);
とかではだめでした。
>440
なんか " と \ の数がおかしくね?
My Documents\2011\01\09(日)
↓
"My Documents\\2011\\01\\09(日)"
↓
"My Documents\\" year "\\" month "\\" date day
だよな?
アドバイスありがとうございます。
はい。
\はおっしゃるとおりですが、依然としてだめです。
today.batをコマンドプロンプトから実行すると、
printしてそのtmp.batを実行する438のパターンだと、
ちゃんとcdできて、今日のフォルダに移動するのですが、
system("cd \\"My Documents\\" year "\\" month "\\" date day);
だと、移動せずに終了してしまいます。
なんでだろーな。
cygwinを入れてやってみた
systemはshで動くっぽいので
rm /cygdrive/c/Documents\ and\ Settings/test.txt
みたいに書くとちゃんと消えるみたい
>>438,442
438で書いてるgawkでやりたいことってのはバッチファイルでやってるのと同じこと?
だったら無理。
system() でcdしてもsystem()から返ってきたところで元に戻る。
どうせ糞nixツールだから日本語や空白はダメなんだろ
>>444 なるほど。gawk内部ではシステムを実行していても、gawkを出ると、それも終わっちゃうんですね。なるほど。
よくわかりました。ありがとうございます。
とりあえずAWKで書いた巨大なスクリプトを、鯖で回し続けるのはやめてください。
非効率極まりない
それはその人に言って下さい
その場で使えるのがawkだけだったんです
450 :
デフォルトの名無しさん:2011/01/19(水) 23:56:54
文字から文字コード取り出せないのが残念
逆はsprintf("%c", 0x41)とか出来るのにな
451 :
430:2011/01/20(木) 00:40:40
>>447 効率のいいプログラムで書き直してやればいいじゃない。
>>450 つord.awk
gawk付属のライブラリで、asciiの範囲の対応表作ってひくという
簡単な仕組み。
#!/bin/gawk --re-interval -f
↑のファイルを実行するとオプションが不正と言われて実行できないのですが
コマンドラインのオプションで指定する以外にやり方はありますか?
>>453 無理にawkスクリプトにせずに
#!/bin/sh
awk '
#awkコード
'
っていうシェルスクリプトにしたらどうかな
#!でインタプリタに渡す引数の扱いは実装依存だからな。
linuxだと空白を含んだ全ての文字列が一つの引数として
渡されるので、複数のオプションは渡せない。不便だけど
そういうものなのであきらめてください。素直にシェルを
間に入れるのがいいと思うよ。
gawk '$3!="*"' in.txt>out.txt
という処理で、20GBぐらいのin.txtを数百MBぐらいにスリムアップしてます。
問題は、その処理を10本ほど並行に作業させているんですが
topで見てみるとほとんどのgawkプロセスがsleepかstackedになっていて
あんまりもりもり働いてくれません。IOが律速なのでしょうか?
CPUもメモリも最大限積んでます。
stacked -> stuckでした。すいません。
458 :
デフォルトの名無しさん:2011/01/21(金) 13:26:09
'$3!="*"'
これって書き間違い?
削られるデータの例
745_17_70_F3 4 * 0 0 * * 0 0 GGAGTGCCCCACACTTGGAGGCGAGCGCCCGGCAGACTTCCCCGCCGCC &+))8'1%+%-%%'((-)%%)8+,&+*7'+/%5''%%%%%-')-/'%/( XM:i:0
残るデータの例
745_377_43_F3 0 chr1 181855450 255 48M * 0 0 CATGTATGTGGCCAAAGGAACAACGCTATGTTTCCTAAAAGGCCTAGA G`[[`a`ab`^\ZYZ[SIR\Z[L7I_L>HU^bOKSDES[PO9-HNG7= XA:i:2 MD:Z:26C21 NM:i:1 CM:i:3
こういうのが80万行ぐらいあるようです。
460 :
デフォルトの名無しさん:2011/01/21(金) 13:52:48
スクリプトの中身は実際は違うわけね
たぶん、データの格納場所がプログラム実行マシンと別のマシンの
ディスクなんじゃないかな。
ネットワークがビジー状態だと思う。
461 :
453:2011/01/21(金) 16:09:37
>454-455
ありがとうございました。
挙動を変える組み込み変数も無いようですね。
462 :
デフォルトの名無しさん:2011/01/21(金) 16:47:10
とりあえず df コマンドで作業ディレクトリと /var/tmp の空き領域が
確保されていることと、出力ファイルのサイズやタイムスタンプが徐々に
更新されていることを確認するくらいしかないんじゃないかな。
ローカルディスクでやればもっと早いと思うけど。
>>460 なるほど。
xgridをつかって、2台のマシンで10本ずつほど並行してgawkを走らせておりました。
NFSをつかって5GBほどの(先ほどは20GBと書きましたが間違いです)in.txtの
のデータを読み込んで、処理後のデータをout.txtに書き出しているので、
ネットワークビジーになってしまうというわけですね。
ネットワークの問題とは。。。
一応、エラーでこけることなく、しゅくしゅくと処理は進むので気にしないことにします。
2台のマシンで20本でした(10+11)。。。
一プロセスあたり5GBのファイルを読み込むので、ネットワークが悲鳴を上げていると。
今年、gawkを大学で習って色々弄ってるんだけど、perlとかより自由度が低いと言われた。そんなに差があるの?
>>465 簡易言語として捉えるかツールとして捉えるかの違いじゃね~
俺パールよりオークの方が好きだけど。
>>466 なるほど。まぁ、そんなに複雑なことをこなすスキルを持ち合わせてないからもう暫くawkで遊んでみるか。
自由度というよりは機能が少ないじゃないのか?
このスレッドは天才チンパンジー「アイちゃん」が
言語訓練のために立てたものです。
アイと研究員とのやり取りに利用するスレッドなので、
関係者以外は書きこまないで下さい。
京都大学霊長類研究所
>>467 perlユーザはすべてをperlだけでやろうとする。C/C++/Javaも使うユーザはawkの方を好む。
C/C++/Javaに手を延ばすつもりならむしろawkのほうがいいよ。perlだと自己完結してしまうから。
perlよりawkの方が速い事ってないじゃん。
今のawkの使い道はワンライナーをコマンドラインのパイプに混ぜる程度でしよ。
俺は、256倍本の長篇スクリプトをいくつか書いたけど、
当時はまだperlなんて使われてなかった。時代が違う。
>>470 それは偏見だろ
autoconfなどの非常に基本的なツールでもPerlが使われているし
opensslのようにconfigureの(主にWindows用の)ポータビリティを上げるために
Perlを利用しているものもある
言語の適性をわかった上で適材適所で使えばいいんだよ
>>471 >時代が違う。
時代と言う意味では、最近はデフォで Python が入っていたりするので
Perl を使うなら Python を選んじゃうな。
あんまり速さを競う仕事をしていないのと、ワンライナーを書く事が
多いので、awk も絶賛大活躍しているけど。
Perl がフルセットの言語なら awk は DSL みたいな物で、個人的には
awk の方が気安く書ける気がする。
pythonは、コマンドラインで使いにくい。
-cで引数に一応コマンド渡せるけど、インデントの問題があるし、
perlの-pや-nみたいに標準入力のループ渡せないから。
質問させて下さい
次のようなテキストがあるとします
aaaaa 10 20 10 5
aaabb 5 10 10 10
aaabb 5 5 5 5
aabaa 5 20 20 30
aabbb 10 10 5 5
bbaaa 10 10 10 10
bbbaa 5 10 10 5
bbbbb 10 5 5 30
ここで、aaaaaなどは個人の名前でかつ、3文字目までが姓、4~5文字目が名前、また数字が出費だとして
各世帯の出費を出力したいと考えています。
aaa 20 35 25 20
aab 15 30 25 35
bba 10 10 10 10
bbb 15 15 15 35
となって欲しい訳です。
で今考えている方法としては
substr($1,1,3) で姓を判定して
同じ姓なら、世帯を加算して行く
違う姓になったタイミングで1つ前の家の家計を print して
さらに各出費を初期化する
次の行に移って同じ世帯なら加算
という感じでスクリプトを組みたいんですが根本的なところでやり方が不味いでしょうか?
連想配列とかじゃ駄目なのか?
name[$1] += 1
>>476-477 全て連想配列に溜め込んで、 最後で一気に出力した方が良くないか?
>>477 の方法だと、 出力を行う箇所が
"姓が変わったとき" と "テキストが終わったとき" に分散してしまう。
{
a = substr($1,1,3);
b[a] += $2;
c[a] += $3;
d[a] += $4;
e[a] += $5;
}
END {
for (f in e) print f,b[f],c[f],d[f],e[f];
}
>>474 OS(Linux)をデフォだけで使うことはまずありえなくて、
何かしら追加パッケージが必要になるはずだから、
Pythonがデフォで入っている事は実用面で評価対象にはならんと思う。
自分はDebianをメインに使うけど、インストール時にはベースシステムだけを選び、
それにsshdとrubyを追加するのがデフォなんで気にならない。
MacならPython/Rubyともデフォで入ってるから無問題だし、
Winならどちらもデフォじゃ入っていないから同じ。
また日常的なプログラミングに関して、Rubyの場合は以下のようにリスト構造を
シェルのパイプライン感覚で書けるのが嬉しい。
hoge_list.select { |x| ....}.sort { |x,y| .... }.map { |x| .... }.inject(n) {|x, i| .... }
ブロック(クロージャ)の無いPyton/Perlでは、こういったお気軽な書き方はできない。
だから日常的な活躍度で比較すると、自分の場合は、bash > awk > ruby になる。
基本はbashで、面倒な文字列処理があればawkをワンライナーで埋め込むのがパターン。
で、色々と機能を追加してきてbashプログラミングが重荷に感じられるようになり、
なおかつ汎用性のある(再利用の可能性がある)ツールであれば、一気にrubyに書き換える。
Pythonは本格的な開発であれば(Rubyよりも)優れた面が多々あると思うけど、
(
>>475の指摘も含めて)お手軽さ/お気軽さに限ると(Rubyよりも)使いづらく感じる。
もちろんbashスクリプト(or Makefile)に埋め込むワンライナーであれば、awk がベスト。
>>474と全く同じ意見だわ。
業務で使う事が多いRHELは余計な物はほとんど入れてない。
Python、Perlがデフォで入ってる感じ。
昔、UNIXを扱ってた頃はPerlならデフォで入ってたので、覚えようとしたけど結局身につかず。
sh、sed、awkでがんばってた。
>>480 デフォで入っているのが嬉しいのは、自分の環境だけでなく、他人の環境でも
使える事が保証されている事だよ。誰かに使ってもらう為のコードを書く時に、
パッケージの追加をお願いしなくて良いのはとても楽。特に、それが仕事で
使われている環境なら尚更。
サポートやトレーニングの仕事をした事がある人なら理解してもらえると思う。
AWKは、NEC PC-9801のMS-DOSでもうごいた。AWK95.exeは、日本語に対応してない
AWKの活躍する場面は、やっぱりテキスト処理だと思う。
そのちょっと複雑版として使うならPerlかな。
組み込みライブラリがテキスト処理に特化してるから。
Pythonは正規表現が言語に組み込まれてなかったりと
テキスト処理は若干やりにくい印象が強い。
その分、テキスト処理以外なら結構使うけどね。
>>482 ああ、それ分かるわ。業務マシンとして使う商用UNIX(HP-UX/Solaris/AIX)だと
RubyどころかPython/Perlすらデフォじゃ入っていないし、そういった
フリーソフトの類いは原則として一切インストール禁止という環境もある。
(Web/MailといったInternet系サーバは別ね。あくまで業務マシン限定の話。)
だから商用UNIXユーザは、デフォで入っているツールに長けることになる。
やっぱり本物のUNIXプロを自称するのなら、python/rubyではなくsh/awkだし、
emacs/vimではなくvi、latexではなくroffを選ぶべきだよね。
>>484 >Pythonは正規表現が言語に組み込まれてなかったりと
へ?
>>486 ん?言語には組み込まれてないだろ?ライブラリとして組み込まれてるだけで。
だから正規表現リテラルとか無いし、importなしには使えない。
リテラルだと何か良いことあるの?
文字列かパターンか区別しやすい。
あと、マッチングの表記が自然。
>>485 Solaris はデフォで Perl も Python も入ってるよ
もちろん入れない事も出来るけど
>>491 それは簡易インストールで用途としてデスクトップあるいはインターネットサーバを
選択した場合の話じゃないのかな。基本システムにperl/pythonは含まれていないはず。
その簡易インストールも含めてデフォであるとするなら、Debianも同じ。
カテゴリでデスクトップを選べば「rubyもデフォ」でインストールされる。(RHLは知らん)
自分は余計な物は入れたくないから基本システムを選んでるけどね。
高可用性を要求される基幹業務システムの場合、自分はHP-UXを扱うケースが多いけど、
デフォでは基本システムを選び事前に設計したパッケージのみを追加するのが鉄則。
なぜならメーカのサポートが受けられない、あるいはあからさまに嫌な顔をされるから。
そんな環境だと、「真にデフォ」なsh/csh/sed/awkが大活躍していたりする。
>>492 Solaris のデフォルトは "Entire Distribution" というパッケージのセットだよ。
インストーラーでデフォルトで選択されているのがこれだし、プリインストール
されているのもこれに近いもの。そこには Perl も Python も入ってる。
インストールする際の選択肢で "Core System" を選べば Perl や Python は
入らなかったと思うけど、これをデフォルトと呼ぶのはちょっと無理があると思うわ。
それと、簡易インストールとかカテゴリでデスクトップとか真にデフォと言った物は
Solaris には存在しない。Debian は知らん。
Solaris2.6あたりのデフォでPerlは入ってた記憶がある。
15年くらい前のHP-UXだとPerlが入ってなかった記憶が。
俺もHP-UXメインだけどPerl入ってないわ
確かに、Solarisに慣れていてHP-UX使わされると使いにくいわー
と言うわけで、UN*Xサーバ管理者の場合はawkを使えるようになっておけば間違いありませんね。
環境を選ばないサーバ管理だったら、sh,grep,sed,tr,cut,paste,sort,uniqあたりで。
nawkとgawkの仕様差が結構あるので、awkは使いにくい。
こういう話題の時にSolarisとかHP-UXは出るのにAIXは出ないイメージ
日本男児ならHI-UX、特にHI-UX/WE2だろ。常識やね
うむ
いやここはedスクリプトで
Solarisは、/usr/bin/awk /usr/bin/nawk /usr/xpg4/bin/awk
3つ別々なのが入ってた気がするな。
で、一番まともなのが3番目なので、よそから持ってきたスクリプトは、先頭の#!を
書き換えないといけないという、カオスな状態じゃなかっただろうか。
>>503 自分アカウントのパスは真っ先に /usr/xpg4/bin/を持ってきてたわ。
スクリプトを組む時はだいたい nawk を使う
他人のスクリプトを丸パクリする機会が無いのでカオスは感じた事が無い
ウチは RHEL と Solaris だけ考えれば良いから、awk で問題がある時は Perl か Python で済ますわ
#!/usr/bin/env [gn]*awk
だろ常考
shebang行に /usr/bin/env 書くのってあんま良いと思えないんだよなあ
複数の引数の扱いとか、環境変数をそこまで信用して良いものなのかとか
あと /usr/bin/ に env があることは本当に保証できるのかとか
/bin/sh を書いたほうが良いんじゃないかって思ってしまう
この話題も定番だな。前スレの558-564でもやってたぞ。とりあえず結論だけを引用しとくわ。
>調べてみたら#!にインタープリタの引数を2つ以上与えたときの
>挙動はOSによって違うようだった。
>
>FreeBSD4.2: 2つ以上あっても渡る(/usrbin/env gawk -f foo)
>Linux(2.6.8): 空白を含めて1つの引数として渡る(/usr/bin/env "gawk -f" foo)
>Soraris(5.8): 2つめ以降の引数は無視(/usr/bin/env gawk foo)
>
>結局/usr/bin/env使った書き方はgawkのインストール位置の差を
>吸収しようとしてるんだろうが、動作はOSによっててんでばらばら
>なのであまりお勧めできないということだろうか。
ruby 界隈でも流行ってるな
意味も判らず「おまじない」と称して使ってるうちに
都市伝説化していくんだな
なぜ gawk には tr が無いのだ
tr("A-Z","A-Z")とかしたいぞ
つ Python
514 :
デフォルトの名無しさん:2011/02/04(金) 09:10:06
>>512 BEGIN {
hankaku="0 1 2 3 4 5 6 7 8 9 A B C D E F G H I J K L M N O P Q R S T U V W X Y Z a b c d e f g h i j k l m n o p q r s t u v w x y z "
zenkaku="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
}
{
for (i=0; i<length(hankaku); i+=2) {
gsub(substr(hankaku,i+1,1),substr(zenkaku,i+1,2))
}
}
それだとtr('ab', 'ba')がうまくいかないんだよなぁ。
516 :
デフォルトの名無しさん:2011/02/04(金) 09:54:40
同じ事じゃん
汎用的に1つ作っとけばいいじゃん
>514みたいなベタ打ちじゃなくて
A-Zあ-ん
こういう表記で置換する方法ある?
tr コマンドって環境によってマルチバイトの扱いが違わね?ウチの場合
Ubuntu10.04に入ってるtr(GNU coreutils)7.4はどうやら2文字扱いにしちゃうらしいが
MacOSX10.5に入ってるtr(バージョン判らんがman見るとBSD系ぽい)は1文字扱いにしてくれた
UNICODE = 文字数
mbcs = バイト数
んーと、どゆこと?
gnome-terminalはユニコード設定のはずなんだが…
他にやらなきゃいけないことがあるってこと?
523 :
デフォルトの名無しさん:2011/02/09(水) 23:11:37
最近、awkの存在を知りました。
いろんな言語を触っては挫折・・・触っては挫折・・・を繰り返していました。
awkは何となくマスター出来そうな気がします。
これから頑張ります!!
256倍の本を今は読んでおります。
gawkでフィールドをソートして表示したいんだが
{split($0, a);asort(a);for(i=1;i<NF;i++){printf("%s%s", a[i], FS);}printf("%s\n", a[NF]);}
よりもスマートな方法ある?
$1~$NFが入った特殊配列みたいなのがあったらうれしいのだが。
>>525 $iとか書けるし代入もできるから
$1~を保存しなくていいのなら、後半は
for(i=1;i<=NF;i++){$i=a[i]} print
と書けばちょっと短くなるな。
>>526 なるほど、そうできるのか。ありがとう。
それは少し古い.
gawk-mbcs-win32-20090920.zip が手元にあるので必要なら再配布するが?
531 :
528:2011/02/19(土) 01:36:10
>>530 もし私に言ってくれているのであれば、
exeのみだけど2009/11/24版が手元にあるので、
これを使い続けようと思う。ありがとう。
俺の手元に、gawk-mbcs-win32-20091124.zip があった。
欲しい人がいて、かつ再配布に問題無いという事がわかればどっかにうpするが。
しかしなんで配布やめちゃったんだろね。
どこからか拝借したコードとかのライセンス問題なのかな?
533 :
デフォルトの名無しさん:2011/02/19(土) 22:51:02.65
>>533 デフォでインストールされるawkでできる範囲のことしかやらないよ
同感。>デフォでできる範囲
長めのスクリプトを書いた事があったのでOOあると便利と思うけど
わざわざインストールするならperl、ruby、pythonがあるしなぁ
awkで書かれたawk++ってないの?
gawkで平仮名・カタカナの部分を抜き出したいと思ってます。
例えば「awkについて語るスレ」だったら
"について" "るスレ" を変数に入れたいのですが、いい方法ありますでしょうか?
538 :
537:2011/03/02(水) 23:17:39.07
「について」と「るスレ」はそれぞれ別の変数に入れたいと思っています
アルファベット以外の部分だったら、アルファベットをFSに指定してwhileで回せばいいけど、
漢字も抜くのは難しいな。
それに、事実上変数は無限に生成するって事か。
matchの第2引数に/[あ-んア-ン]+/を持ってくるとか?
541 :
デフォルトの名無しさん:2011/03/03(木) 13:28:46.50
$0,$1...$NFを壊してもいいんだったら、私ならこうします。
gsubの検索文字鉄には正規表現を使用することができるから、
ひらがなとカタカナ以外の文字をスペースに置き換える。
gsub(/[^ーぁ-んァ-ン]/," ")
ひらがなとカタカナ以外の文字は半角スペース2つに置き換わる。
あとはNFを見て表示したいように処理する。
注意すべきは、Windows版の新しいバージョンのものでは、
正規表現として、ひらがなを ぁ-ん で、カタカナを ァ-ン で
指定できないものがあります。
たしかマルチバイト拡張で壊された。
542 :
537:2011/03/03(木) 14:28:35.14
>541
まだ試してませんが、欲する文字以外を消してゴニョゴニョすればいけそうです。
>539-540さんもありがとうございました。
543 :
デフォルトの名無しさん:2011/03/03(木) 19:41:21.36
BEGIN {
str = "デンコ漢字ばんざい元気abcdeだから"
c = split(str, a, "[^ーァ-ンぁ-ん]")
for (i = c; i>=1; i--) {
if ( a[i] !~ /^$/ ) { print a[i] }
}
}
ボケかました
4行目は普通に
for ( i = 1; i <=c; i++) {
でOK。
cを残さなくとも
for (i in a){if (a[i]) print a[i]}
で間に合うような。
for-inだと順序が保障されないんじゃなかったっけ?
547 :
デフォルトの名無しさん:2011/03/04(金) 08:34:52.75
for ( i = 1; i in a ; i++) って書き方もできるよ
548 :
デフォルトの名無しさん:2011/03/07(月) 14:14:11.11
a1 a1 a1 a2 a2 a3
b1 b1 b1 b1
c1
d1 d2 d2
....
のように、フィールド数がバラバラで、フィールドが一致する場合もあれば
一致しないデータがあるのですが、重複を
a1 a2 a3
b1
c1
d1 d2
のようにまとめあげるにはどうしたらよいでしょうか?
さすがにググってコピペという訳にもいかず。。。
>>548 いろいろやり方はあると思うが
awk '{j=0;delete a;for(i=1;i<=NF;i++){if(!a[$i]++){$(++j)=$i}}NF=j;print}'
550 :
デフォルトの名無しさん:2011/03/07(月) 14:53:42.21
ありがとうございます。
それぞれ、4つ重複データのあったものは3つに、2つのものは1つにと減ったのですが
それ以上減ってません。同じコマンドを繰り返しかけてみたのですが、変化はなかったです。
a1 a1 a1 a1
b1 b1 b1
...の部分が
a1 a1 a1
b1 b1
にはなったという意味です。
もう少しおつきあいいただけないでしょうか。。。
手元では一つになるけどなぁ。原理はわかるだろうからあとはがんばれ。
行ごとにフィールドの添字についてループするのと連想配列で出現チェックがキモ。
% cat hoge.txt
a1 a1 a1 a2 a2 a3
b1 b1 b1 b1
c1
d1 d2 d2
% awk '{j=0;delete a;for(i=1;i<=NF;i++){if(!a[$i]++){$(++j)=$i}}NF=j;print}' hoge.txt
a1 a2 a3
b1
c1
d1 d2
552 :
デフォルトの名無しさん:2011/03/07(月) 15:14:33.26
0610005C13Rik 0610005C13Rik 0610005C13Rik
0610007C21Rik 0610007C21Rik 0610007C21Rik 0610007C21Rik 0610007C21Rik
こういう感じの文字列なんですが
a1とかb1で例えても大丈夫だったですか?
空白で区切られた文字列ならなんでもいいが、そのレベルの質問が
出るようじゃもうすこし基礎を勉強しないとだめかもなぁ。
シングルクオーテーション使用のサンプルで問題ないと言う事は~
UNIX環境なのかな~
555 :
デフォルトの名無しさん:2011/03/07(月) 15:58:11.87
Mac OSXのターミナルを使ってます。
>>551はそのままうまく動きました。
いま昇順で手動で作業してますが、まだzを抜けることができません。
もう手がつりそうです
一行野郎を分解してスクリプトに組み直して弄れば動作確認出来ると思う
557 :
デフォルトの名無しさん:2011/03/07(月) 16:21:10.50
まだやってるのか~
ファイルの ^M が問題みたいだから
CRLFのファイル形式に変換して上の一行野郎で問題ないみたいだったよ。
559 :
デフォルトの名無しさん:2011/04/19(火) 03:07:46.46
#複数行の入力中、先の行の11カラム目にOUTが含まれているかつ次の行の11カラム目にINが含まれている2行が揃った時、2行を出力
$11~/OUT/{ prev=$0; }
$11~/IN/{
if(prev!=""){ print prev; print; }
prev="";
}
560 :
デフォルトの名無しさん:2011/04/19(火) 15:55:50.78
# 7.awk
NR >= 2{
if($0 ~ /^>'=+/){
if($0 ~ /~$/){
print "A";
}else{
print "NAA";
}
}else if($0 ~ /^>\^(Q=)+/){
if($0 ~ /~~$/){
print "B";
}else{
print "NAB";
}
}else{
print "NAC";
}
}
7.txt
3
>'======#======~
>^Q=Q=Q=Q=Q=Q=Q=Q=~~
>'===#====~
NAA
NBB
NAA となる。何で?
A
B
A となってほしいのに・・・gawk 3.1.7です・・
俺の手元のgawk 3.1.7では期待通りの結果になるなあ。
行末がらみだと改行コードが違ってたり見えない空白が
入ってたりというのがよくあるので確認してみ。
>>560 あと
/^>'=+/
ってキャプチャとかしてるわけじゃないから+は無駄じゃないか。
563 :
デフォルトの名無しさん:2011/04/19(火) 16:45:20.75
>>561 ありがとうございました。改行コードをunix形式にしたら出来ました。
今後ともよろしくお願い致します。
564 :
デフォルトの名無しさん:2011/04/19(火) 17:00:39.34
>>559 INがあるときにしかprevがクリアされていないから、OUTが出現した以降に
複数行が経過してもINが出現するとprintされるスクリプトになっているよ。
565 :
559:2011/04/20(水) 01:08:11.06
566 :
デフォルトの名無しさん:2011/05/01(日) 16:22:39.39
http://okwave.jp/qa/q6660984.html #2列目の項目がdisk1~4まで不足部分が埋まるようにし、不足していた部分の1列目には前の時間、3列目には0で埋めたい
BEGIN{ dt=prevDt="00:00:00"; }
NF>=3{ dt=$1; tgt=$2; n=$3; }
NF==2{ tgt=$1; n=$2; }
{ gapDisp(prevTgt,tgt); disp(dt,tgt,n); prevDt=dt; prevTgt=tgt; }
END{ gapDisp(tgt,"disk1"); }
function disp(dt,tgt,n){ print dt, tgt, n; }
function gapDisp(disk,endDisk, cnt)
{
for(cnt=add(getNo(disk)); cnt!=getNo(endDisk); cnt=add(cnt)) disp(prevDt, sprintf("disk%d", cnt), 0);
}
function add(cnt){ return ((++cnt>4)?(1):(cnt)); }
function getNo(disk){ sub(/disk/,"",disk); return disk; }
BEGIN { reset() }
NF == 2 { $3 = $2; $2 = $1; $1 = last_t }
{ last_t = $1 }
{ if ($2 < last_disk) { p(); reset() } last_disk = $2 }
{ n[$2] = $3 }
{ for(i in n) { if (i >= $2) { t[i] = $1 } } }
END { p() }
function p() {
for (i = 1; i <= 4; i++) {
d = "disk" i
print t[d], d, n[d]
}
}
function reset() {
for (i = 1; i <= 4; i++) {
d = "disk" i
t[d] = t["disk4"]
n[d] = 0
}
}
568 :
デフォルトの名無しさん:2011/05/03(火) 14:58:05.53
間違ってるよ
しかも長くて美しくないよ
http://okwave.jp/qa/q6711117.html ...こんな感じかねぇ? awk -f sum.awk データ | sort
----- sum.awk -----
$1!~/商店名/{ tbl[$1 "," $2]+=$3; }
END{
for(key in tbl){
split(key, item, /,/);
print item[1], item[2], tbl[key];
}
}
-----
>>566 NF==3 {
disp();
for(i=1;i<=4;i++) {
disk_time[i]=$1
disk_val[i]=0
}
disk_val[substr($2, 5, 1)]=$3
}
NF==2 {
disk_val[substr($1, 5, 1)]=$2
}
END{
disp()
}
function disp() {
for(i=1;i<=4;i++) {
if(i in disk_time) printf("%s disk%d %s\n", disk_time[i], i, disk_val[i])
}
}
BEGIN {
# 先頭がいきなり "disk2 15" のみで始まったりしなければ
# この初期化は不要。
a = "00:00:00";
}
NF == 3 {
if (NR > 1) put();
a = $1;
b[$2] = $3;
}
NF == 2 {
b[$1] = $2;
}
END {
put();
}
function put( i) {
for (i = 1; i <= 4; i++) {
print a, "disk" i, b["disk" i] + 0;
b["disk" i] = 0;
}
}
>>569 awkの配列ってどれくらい確保可能なの?
先にsortしたらどうかな? sort データ | awk -f sum.awk
----- sum.awk -----
$1!~/商店名/{ if(store==$1 && item==$2) val+=$3; else{ disp(); store=$1; item=$2; val=$3; } }
END{ disp(); }
function disp(){ if(store!="" || item!="") print store, item, val; }
-----
ヘックション
$ uname -sr
CYGWIN_NT-6.1 1.7.9(0.237/5/3)
$ awk --version
GNU Awk 3.1.8
この環境で、
awk 'BEGIN {for(i=j=1;i<50;++i) {print j; j*=10}}'
これ実行すると、jが23桁超えたあたりから、おかしくなるんだけど。
awkの整数って上限あるの?(ウチだけか?)
long double辺りの精度しかないよ。
576 :
デフォルトの名無しさん:2011/05/06(金) 09:18:39.10
>>574 おれのPCでは普通に 1 から 1e+048 まで表示されますが。。。
>>576 本当ですか!よろしければ環境を教えてください。
>>577 ありがとう。ここawkも張れたんだ。結果が長すぎて困ってたのよ。
正にこんな結果になる。
POSIXで保障されてる精度は
>>575ってこと?
てことは、awkは内部では、全ての数がdouble扱いなの?
579 :
デフォルトの名無しさん:2011/05/06(金) 14:20:04.87
>>578 576です。WindowsXP + GNU Awk 3.0.6 + multi-byte extension 1.15 です。
>>579 ありがとう。
あまり違いがないな。Win7は関係ないだろうし。
multi-byte extensionがその辺りも弄っているのか…
そういえば、1e+048みたいな指数で表示されるの?
出力のとき丸めるから、ちゃんと計算できてるように見えるのかな。
awkでは数値はすべてdoubleで扱います。
ですからその精度である53bit分、大体15桁ちょっとを超えると正確な値を保持できません。
23桁あたりまで正しく表示できてるってのはよくわかりませんが、
3.0.6にしても出力時の書式指定が違うだけで内部的には同じように不正確な値に
なってしまってると思います。
だから、実質long doubleの精度になっているんだってば。
>>582 「実質」というのはどういう意味?
#define AWKNUM double
ってのがあるし、long double にしても仮数部は64bitだから23桁には足りないよ?
x87のレベルで拡張精度になってても、表示やらなんやらするところで倍精度に
丸められちゃうと思うんだけど。
>>581 あう、そうなのかー。ありがとうございます。困ったなぁ。
10進で実数扱えとまでは言わないけど、整数は欲しい。
数をいろんな型で扱える処理系なんてないか。
>>583 あー、long doubleと言ったのが拙かったね。10の冪の場合は実質doubleを大きく越えた精度になっていると言いたかった。
10は2と5の積だから、10倍を繰り返すときに仮数部は5倍ずつにしかならない。
IEEEのdoubleの精度だと5の22乗で53ビットを使い果たすので、そこまでは誤差が生じない。
言い換えれば、10の場合は53ビット+22ビット、即ち75ビット分精度があるように見える。
まぁ、>584を10倍じゃなくて5倍にして、doubleをlong longにして%.fを%llxにしてビット数を数えてみればわかるでしょ。
gawkのユーザガイドに、他の処理系では、標準エラーを使うため、
print "Serious error detected!" | "cat 1>&2"
という方法しかないとあります。
gawkは/dev/stderrを特別に扱うため、
print "Serious error detected!" > "/dev/stderr"
と書くのが適切とあります。
これには、どのような違いがあるのでしょうか?
/dev/stderrがあるOSなら、catのプロセスが生成される他は、違いはないのでしょうか?
環境や処理系を問わず動作させたいなら、上の書き方の方がよいのか、気になっています。
よろしくお願いします。
他の処理系って、他のawkって事だよ。
/dev/stderrがあるOSって事ぢゃなくて、
gawkは特殊なファイル名として/dev/stderrとか使えるよ、って事だよ。
なので他のOSでも gawk だったらprintとかの出力先ファイル名として /dev/stderr 使えるって話だね。
/dev/stderrとかをサポートしていないgawk以外のawkでも動作させるなら パイプと"cat 1>&2"を使う方法しかない。が、Win系はcatだと...
そこまでのことをするならPerl/Ruby/Python等のちゃんとした
スクリプト言語で書いた方がいいんじゃないかな。こういう
どうでもいいところで悩まなくて済むよ。
awkはawkで手軽に書ける範囲なら他の追随を許さないと思うが
その枠をはみ出ようとすると途端に大変になる。そこが楽しいと
いうのなら無理には止めないけどw
>>588 ありがとうございます。
catがない環境だと、どうしようもないですね…
>>589 コンマ区切りのデータを、シェルスクリプトで処理していたので、
それをawkに移植していました。一番手軽だったのです。
ちなみに、2時間半以上かかっていた処理が、1分以内に短縮されました。
ワラタ。 ワラタ…
Cで書き直したら数秒で実行完了の予感w
つーてもawkとかその他のスクリプトでサクッと書けるような文字列処理を
C言語とかではあんまり書きたくならんと思うぞw
なりません
あぁああぁぁぁ~~~無理だったか、、無理なのかー!a[0][0] = 1 → syntax error
>>595 gawkの場合インデックスをSUBSEP(=\034がデフォルト)を挟んでシリアライズしたインデックスで多次元配列を表現する
a[0,0] = 1;
ならOKのはず。このときのインデックスは"0\0340"だから、a["0\0340"] == 1。
>>596 ありがとう。始めからそれを意識して書いてたらよかったんだけどね。
god["name"] = "Kaname Madoka"
god["msg"] = "Mahoushoujo ha watashi dakede juubun dayo."
homerun["name"] = "Akemi Homura"
homerun["msg"] = "Madoka ha watashi no yome."
こんな風に書いていたのを、
puella_magi["god"] = god
puella_magi["homerun"] = homerun
みたいにまとめようとしたら、あばばばば
awkの配列って処理系によっては添え字が整数の場合、処理が最適化されて早くなったりするのかな?
構造体の代わりみたいに使いたかったのだが。
name["god"] = "Kaname Madoka"
msg["god"] = "Mahoushoujo ha watashi dakede juubun dayo."
name["homerun"] = "Akemi Homura"
msg["homerun"] = "Madoka ha watashi no yome."
でよくね?
awkって *どの実装でも* 一度も使ったことがない変数の内容って、スカラなら0か""になってるの?
変数が一度も代入されていないことを判定するために、(x==0 && x=="")って書いて何か問題ない?
>>599 評価されるときに変数が存在しなければ作成される。はず
配列の要素なら in で調べられるけど
変数自体となるとどうだろうね
>>599 何度も代入した後、最後に 0 or "" を代入した変数と区別できない。
>>600-601 ありがとう。区別できないって、どういう状態になるの?0を代入したら0か"0"に評価される。
ああ、""を代入したら0か""に評価されて駄目ってことか!?
あれ?試したらどっちを代入しても599の式は0に評価されたよ。区別できないケースってどういう場合?
BEGIN {
# 初期化直後 (未使用) の変数は数値 (0) と文字列 ("") の両方の型を持つ。
print x == 0, x == ""; # 両方とも真
x = 0;
print x == 0, x == ""; # 前者のみ真。
x = "";
print x == 0, x == ""; # 後者のみ真。
# 他の未使用の変数を代入すると "再初期化" できる。
x = y;
print x == 0, x == ""; # 両方とも真。
}
> 初期化直後 (未使用) の変数は数値 (0) と文字列 ("") の両方の型を持つ。
IEEE Std 1003.1 の awk の EXTENDED DESCRIPTION の
Variables and Special Variables に書いてあるね。 uninitialized value というらしい。
POSIXに準拠してるawkならこうなるみたいだけど、オリジナルは知らん。
再初期化するなら$(NF+1)使うほうがいいかもね。未使用の変数を用意しなくていい。
だけど、それが必要な場面が思い浮かばないが。
関係ないけど、abs関数ってないんだね。別に良いけど、πや、
0より大きい最小の浮動小数点数は定義しててほしいなあ。
>>605 > 再初期化するなら$(NF+1)使うほうがいいかもね。未使用の変数を用意しなくていい。
フィールド変数は常に文字列型で、 数値型は持たない。
607 :
デフォルトの名無しさん:2011/06/02(木) 22:47:31.10
πはatan2(0,-1)でいいとして
「0より大きい最小の浮動小数点数」ってどう定義していつ使うの?
「0より大きい最小の浮動小数点数」というのが何を希望しているかによる。
以下の3種類がある。
(1) 最小の正の非正規数
(2) 最小の正の正規数
(3) 1.0に足して丸めた結果が1.0より大きくなる最小の数
>>606 あちゃ!そうでした。$で戻るのは文字列だった。
その仕様書読んでると、NFを拡張したとき、元々なかった所はuninitialized valueになるってあったので。
>>607 それでいいんだけど、PIとかで参照できたらもっといい、と思ったのです。
>>608 数値計算のために、CのDBL_EPSILONの代わりになる定数が欲しいなと。
任意の精度で丸められる関数もないですし。
DBL_EPSILONが
>>608の(1)~(3)のどれかわからない?
数値計算の基本なんだが。
611 :
デフォルトの名無しさん:2011/06/10(金) 21:49:33.34
変数名など、自前であっても規則を意識している方いますか?
awkだと、C風が一般的なのでしょうか?
一番最初がVBAだったので、長い名前と省略が混ざってしまって
自分でイライラしています。
みなさんの、通常の変数はこう、配列はこう、定数はこう、文字型はこう・・・
というものを参考にしたいです。
>>611 システムハンガリアンを採用するかどうか悩むほど大きなものをawkで書いたことが無い
613 :
かあた:2011/06/13(月) 18:37:34.88
、5なわやあふぉt( ())
>>611 遅レスだが、型_内容の説明_名前みたくしてる。名前が一文字だとそのままだけど。
グローバル変数とローカル変数のどっち弄ってるのか分かりやすいように、ローカル変数は必ずlで始めるようにしてる。
d_per_shouhizei = 5.0とかね。
615 :
デフォルトの名無しさん:2011/06/20(月) 18:37:26.17
gawkでBINMODEを設定すればバイナリーの入出力ができるのはわかるのですが、
入力されたバイナリーを16進ダンプして表示するにはどうしたらよいでしょうか?
od等の外部コマンドを使う意外に方法があればお教えください。
printf("%02x\n", $1);
二度と話かけんなよ
お前らってどうみてもゴミだよな
ゴミんなさい
>>595 gawk4.0.0でa[0][0]=1も可能になったじゃないか
超初心者の質問で申し訳ありません。以下のようなデータを
aaa 10
bbb 20
ccc 30
aaa 30
bbb 30
aaa 15
ccc 30
ddd 20
以下のようにまとめたいのですが、どうしたらいいでしょうか?
aaa 55
bbb 50
ccc 60
ddd 25
ddd 20 ではないかと思うがこんな感じかな
awk '{a[$1]+=$2} END {for (b in a) {print b " " a[b]}}' | sort
Gawk4ならPROCINFO["sorted_in"]の設定で最後のsortが要らなくなる
623 :
620:2011/07/30(土) 23:22:20.03
>621
ありがとうございます!うまくいきました。
gawkはもう別言語なイメージ。普段mawk使ってると
ここって生きてますか?
生きてますん
628 :
627:2011/08/19(金) 01:00:20.60
TEST.DATは、空白が入っています。
専ブラのポップアップをコピペして下さい。
ウチに帰ってから調べてみるよ
>>627-628
cygwinのawk(GNU Awk 3.1.8)で動くけど、どうなるはずがどう動かないと言っている?
>627のtest.datなら、当然「ソ」だけが変換されるけど。
(CygwinならUTF8じゃないとうまく動かないけど)Shift JISで動作させたいってことかな?
事前にTEST.DATをnkf -wに通したら駄目かな。
632 :
629:2011/08/19(金) 21:59:57.43
>>627 スクリプトもDATもSJISで試したけど、上記3つのうち、gawk-mbcs-win32-20051223.zipはダメだったよ。
1行目がこんなんなる。
アxxエオカキクxコサxxxソ
手持ちの
GNU Awk 3.1.7(windows special Nov 24 2009)
で、--ctype=SJISやっても同じ結果になるね。
スクリプト、DATをUTF-8にして、--ctype=UTF8やってリダイレクトしたファイルは正常な結果が出るよ。
リダイレクトしないでコマンドプロンプトに表示させると化けるけど。
EUCなら半角カナもうまくやってくれるんだが…
634 :
デフォルトの名無しさん:2011/08/24(水) 08:07:37.54
gawkはガンガン機能を拡張してるけど、
そろそろOOP対応してくれないかな。
awk++とかあるけど、標準でOOPできれは便利。
> OOP
...もはやawkでやる意味が無いw 他にいくらでもある別の言語でいいじゃん
awkに在ると便利かもと思うのは参照値くらいかな
配列や関数への参照を値として取り出し格納したり
逆にその値から元の配列にアクセスしたり元の関数を呼んだり出来ると
相当に複雑なデータ構造が表現可能になる、それこそOOPっぽいことも可能だし
でもあんまりややこしいことやるならPerlでいいから必須ではないね
> 関数を呼んだり
変数の値を関数名として
var = "sage";
@var();
ってできるけど、それとは違うのん?
およ、もうあるのかw
最近のawkは分からねえ…ってことは、配列への参照を使って入れ子の配列とか既に作れちゃったりするのか?
配列の配列は作れるよ。gawk4なら。
(´_ゝ`)フーン
641 :
デフォルトの名無しさん:2011/08/25(木) 20:52:51.07
class human {
property name
property sex
property age
method new(x, y, z) {
name = x
sex = y
age = z
}
method say() {
printf("私は%s。%d歳の%sです。\n",name, age, sex)
}
}
class japanese : human {
property name
property sex
property age
method say() {
printf("私は%s。%d歳の%sです。国籍は日本です。\n", name, age, sex)
}
}
BEGIN {
alice = human.new("アリス", "女", 11)
taro = japanese.new("太郎", "男", 15)
yuka = japanese.new("由佳", "女", 18)
alice.say()
taro.say()
yuka.say()
}
642 :
641:2011/08/25(木) 20:58:10.41
それは最早awkである必要が全く無い
function Human(self,name,sex,age) {
self["property___name"] = name
self["property___sex"] = sex
self["property___age"] = age
self["method___say"] = "Human___say"
}
function Human___say(self) {
printf "私は%s。%d歳の%sです。\n", self["property___name"], self["property___age"], self["property___sex"]
}
function Japanese(self,name,sex,age) {
Human(self,name,sex,age)
self["method___say"] = "Japanese___say"
}
function Japanese___say(self) {
printf "私は%s。%d歳の%sです。国籍は日本です。\n", self["property___name"], self["property___age"], self["property___gender"]
}
function methodcall(obj,methodname, m) {
m = obj["method___" methodname]
@m(obj)
}
BEGIN {
Human(alice, "アリス", "女", 11)
Japanese(taro, "太郎", "男", 15)
Japanese(yuka, "由佳", "女", 18)
methodcall(alice,"say")
methodcall(taro,"say")
methodcall(yuka,"say")
}
ごめん一部genderになってるからsexに直しといて
とりあえず、こんな感じでgawk4でもOOP自体は出来るよって話
646 :
デフォルトの名無しさん:2011/08/27(土) 15:07:17.61
>>644 なるほどねー
とても勉強になります
でも、やっぱりOOP用の構文が使えればベストですね
そのほうがわかりやすいと思います
やっぱ別言語使うべきだろ
本当に欲しいんなら、gawkのMLにこうすればOOP実現できることを発見したんだけど、
これの糖衣構文を用意してくれって投稿するといいんじゃね
switchも実装されてるし、欲しい人が居ると分かれば付けてくれるかもよ
#! /usr/bin/env python
# -*- coding: utf-8 -*-
class human:
def __init__(self, name, sex, age):
self.name = name
self.sex = sex
self.age = age
def say(self):
print("私は" + self.name + "。" + str(self.age) + "歳の" + self.sex + "です。")
class japanese(human):
def __init(self):
super(human, self).__init__(self)
def say(self):
print("私は" + self.name + "。" + str(self.age) + "歳の" + self.sex + "です。国籍は日本です。")
if __name__ == "__main__":
alice = human("アリス", "女", 11)
taro = japanese("太郎", "男", 15)
yuka = japanese("由佳", "女", 18)
alice.say()
taro.say()
yuka.say()
pythonで書いてみると、
>>641と比べると特にわかりやすいわけでもないけど
>>644よりはわかりやすい
そりゃawkはOOPLではないからな
あくまでシェルのお供でいいと思うんだ
そしてそこに高度なOOP機能は要るとは思えない
どちらかと言えばフィールド抽出とかをもっと便利にすべきだよ
cygwin以外でgawk4.0をwindowsで使おうと思ったら、バイナリはどこで入手できもうすかね?
cygwin で駄目な理由が分からないから教えられない。
>654 さんくすこ
>653 awkの実行形式だけ入手すれば良いようにしたいのさ。
バイナリ互換のWindowsなのに、cygwinてexeをもってくだけじゃ使えないの?
物によっては使えたような気がする。
cygwin1.dllだっけ?にパスが通ってれば大体使えたような気がする。
結構沢山のdllが要るよ
コマンドによるけど
>>659 比較関数の与え方はPROCINFO["sorted_in"]の場合と同じってことだろ。
自分で定義した関数の名前でもいいし、11.2.1.2に書いてあるようにすでに用意
されている@~を使ってもいい。
個人的には、GAWKにはあと、Cで書いた関数の呼び出しというか
GAWKで呼ぶ関数をCで書ける機能が欲しいと思ってるんだけど、
ここ見る限り世間的にはあんまり需要ないんかねぇ。
まぁ、それやるくらいならGAWK自体に変更を加えて再コンパイルしろってことかもしれないけど。
PとかR使え言われると思う。
最近awkcardを知って座右に置いてるのだが、日本語版って存在するのだろうか。
666 :
デフォルトの名無しさん:2011/12/22(木) 16:57:35.32
>>666 その通りにやったと言うのなら、何故poファイルを提示しないのかね、ダミアン君。
>>667 poは作成しましたし、moも所定のディレクトリにあります。
poは自分で編集しても、そのサイトの内容をコピペしてもダメでした。
$ cat gettext.po
#: gettext.awk:10
msgid "********** Count Prime Number **********"
msgstr "========== 素数を数える =========="
#: gettext.awk:14
msgid "2 is a prime number."
msgstr "2 は素数です。"
#: gettext.awk:24
msgid "%d is a prime number.\n"
""
msgstr "%d は素数です。\n"
$ ls ja_JP/LC_MESSAGES/
gettext.mo
結果はこの通りです。
$ LC_ALL=ja_JP gawk -f gettext.awk 10
********** Count Prime Number **********
2 is a prime number.
3 is a prime number.
5 is a prime number.
7 is a prime number.
ずいぶんawkから離れていて久しぶりに使ったら
nawkに日本語のバグがあることにしばらく気づかなかった
substr()でutf-8のテキストを切り出すとおかしな値になる
gawkでは直っている
そもそもUTF-8に対応してたっけ
Linuxでは普通に動くが…
ファイル名が"*.txt"の一覧を取得するとき、"\.txt"でマッチさせると、任意の一文字.(ドット)と解釈されてしまうんですが、いい方法無いでしょうか?
GNU Awk 3.1.7だとドットにマッチしたけどそもそもawkの話?
具体的にコマンドがほしいな
昭和の頃覚えたアセンブラとC言語
これがあったから
いまだに自分が損な業界で飯を食ってる
>>676 そこからjavaに行ってスマホアプリ開発ならもう一花咲いたかもしれませんねw
馬鹿には無理
679 :
674:2012/04/30(月) 18:07:43.22
>>675 ls | awk '{ if( match($0,"\.txt") > 0) print $0 }'
↑会社のサーバ上でこんな感じのことやろうとしてたんですが、
「gawk: 警告: エスケープシーケンス `\.' は `.' と同等に扱われます」
とメッセージが出力され、ドットが任意の一文字?と解釈されて困っていましたが、
自己解決しました。(自宅のLinuxPCで動作確認しました。GAWK3.1.7及び4.0.1)
"\.txt"では無くて、".txt"で良かったんですね。
お騒がせしました。
もしかしたら、会社のサーバ(RHEL)のGAWKが古くて解決できてないかもしれませんが。
FIFOな感じの先入れ先出しのバッファには何使えばいい?
というか、
Arrayで、たとえばA[3] からA[8]までのデータをA[1]からA[6]に動かすには何が一番早い?
できれば配列は1つしか使いたくないのだが、無理だろうか…
速さを求めるなら毎度全要素ずらすより、読み出し位置と書き込み位置の添字持って
管理した方がたいてい速い
awkには連想配列しかないしな
リングバッファで何とかなるならリングバッファかな
>>682 BEGIN{
QMAX=3
QTopPos=0;QTailPos=0;QNum=0;
deQ();
enQ("1");deQ();
enQ("a");enQ("b");enQ("c");enQ("x");deQ();deQ();deQ();deQ();
}
function enQ(PushVal){
if (QNum+1 > QMAX){print "おなかいっぱい"; return;}
nextPos = (QTopPos+1) % QMAX;
queue[QTopPos] = PushVal;
QTopPos=nextPosQNum++;
}
function deQ(){
if (QNum < 1){print "からっぽ"; return}
QNum--; TailVal=queue[QTailPos]
QTailPos = (QTailPos +1) % QMAX;
print TailVal;
return TailVal;
}
687 :
686:2012/07/14(土) 22:54:06.64
↑の結果はこんな感じ。
>からっぽ
>1
>おなかいっぱい
>a
>b
>c
>からっぽ
>>685の書いているリングバッファ実装です。
enqueue,dequeue回数が多いならリングバッファで良いと思う。
大抵の場合はQMAXに大きな値を設定すれば事足りるハズだけど
上限が決定できない等の事情があればdelete arrayを使った単純な配列管理かな。
ただ添え字が数値上限を超えない様な工夫は必要だね。
リングでも上限を定めると入力ストリームの上限が不明な場合まずいことになるので、現在は
A=入力Array,C一時保管,i,k,n,p
k=1;C[0]=0;
for(i=1;i<=A[0];i++){n=0;while(k<i && A[k++]=C[n+=1]);if(n){
delete C[C[0]+1];C[0]-=n;p=0;while(C[p+=1]=C[n+=1]);}p=1;
while(match(substr(A[i],p),re)){p+=RSTART-1;n=substr(A[i],p,RLENGTH);
if(k<i){A[k++]=n;}else{C[C[0]+=1]=n;};p+=RLENGTH;}};n=1;
while(A[k++]=C[n]){delete C[n++];};A[0]+=C[0]-1;C[0]=0;
を使っている。
re=regexpとして、Array Aに一致するデータがあれぼそれを取得、結果をArray Aに出力、A[0]に合計が記載。
これ以上(コードサイズ、ある程度の速度、メモリの使用量を極力少なく)という条件で最適化できるだろうか…
だれか頼む。
入力と出力先が同じでも、別でも作動するコードなら尚のこと良いのだが…
これはひどい
デバッグも拡張も無理じゃね
基本的に一度作って後は必要に応じてコピペだがらな。他には
function grep( o, re, p, B, this, a ){
B[0]=0;if(o~"-v"){while((getline v < p)>0){if(!match(v,re))B[B[0]+=1]=v;}return B[0];};
if(o~"-o"){while((getline v < p)>0){a=v;while(match(a,re)){B[B[0]+=1]=substr(a,RSTART,RLENGTH);
a=substr(a,RSTART+RLENGTH);}};return B[0];};while((getline v < p)>0){if(match(v,re))B[B[0]+=1]=v;}return B[0];
}
なんかも良く使う。grep("-o","pattern","/var/log",data);みたいな感じで。前のはagrep("-v",pattern,B,C)の一部分。
日ごろのメンテでちょっとした手作業じゃめんどいの組むときに、ほぼ数分で組みあがるのが楽なんだよ。
サブプロセスとしてgrep呼び出すのがコストかかる時とか、perlが破損した状況でのリカバリースクリプトとして組んだのが元だけど。
カーネルさえ生きていれば後はawkバイナリ流し込めば使え、shが半分死んでいてもなんとか動くし。
691 :
686:2012/07/21(土) 23:12:03.74
>>688 BEGIN{
QMAX=9007199254740991
QTopPos=QTailPos=QNum=0;
hitTop=0;
A[++z]="hoge";
A[++z]="1 2 3 4 5";
A[++z]="fuga";
A[0]=z;
for(i=1;i<=A[0];i++){
p=1;
while(match(substr(A[i],p),/[0-9]+/)){
p+=RSTART-1;
enQ(substr(A[i],p,RLENGTH));
p+=RLENGTH;
}
if(QNum>0){
while(QNum && hitTop<i)A[++hitTop]=deQ();
}else{
delete A[i];
}
};
if(QNum>0) while(QNum)A[++A[0]]=deQ();
for(z=1;z<=A[0];z++)print "A[" z "]:" A[z];
}
692 :
686:2012/07/21(土) 23:44:24.03
691の続き
ちなみに、A[1]~A[A[0]]をgrepして結果はA[1]~A[?]に戻すスクリプトね。
複数件マッチする事があるので未処理行を上書きしないようにキュー使ってる。
function enQ(PushVal){
if (QNum+1 > QMAX){print "Queue Overflow"; exit;}
nextPos = (QTopPos+1) % QMAX;
QBody[QTopPos]=PushVal;
QTopPos=nextPos
QNum++;
}
function deQ(){
if (QNum<1){print "Illigal dequeue"; exit;}
QNum--;
TailVal=QBody[QTailPos];
delete QBody[QTailPos];
QTailPos=(QTailPos +1) % QMAX;
return TailVal;
}
リングバッファの上限超えたら終了させてるけど
>>688の実装も上限超えたらバグるし許して。
計ってないけどループがない分早い筈。コードサイズはお察し。
メモリはA[]にデータ抱えてる時点でアウトな感じだけどA[]を適宜消すようにしといた。
出力先を別にしたいならA[]にdeQ()せず別変数にすればおk。
これで良い?
693 :
688:2012/07/22(日) 09:36:17.43
>QMAX=9007199254740991
ワロタwww
俺のも確かにwhile(C[p+=1]=C[n+=1]);の部分で保持してるのすべて消費分だけ上に移動させてるのが無駄なので
そのループが無い分は確かに早いはず。
あと、恥ずかしながら尋ねたいのですが、俺
>>688の実装で上限超えたらバグるをkwsk
なんか見落としてたのか今更ながら心配になってきた。
昔作ったやつなんで、結構な頻度使ってきたのだが今までバグに気づかなかった
しかしデータをメモリ上に展開するからどうしても上限が出てくるな…
awkで10GBぐらいの扱う時はgetlineでなんとかなるけど、やはりメモリマップやポインタが使えたら便利だよなぁ
パッチ作ったら需要あるかな?
>>693 691、ちょっと訂正。無駄にキュー使う分、元スクリプトから劣化してた。
> p+=RSTART-1;
>- enQ(substr(A[i],p,RLENGTH));
>+ if(hitTop+1<i){
>+ A[++hitTop]=substr(A[i],p,RLENGTH)
>+ }else{
>+ enQ(substr(A[i],p,RLENGTH));
>+ }
> p+=RLENGTH;
あと、良く考えたら出力先を別にするなら、そもそもキュー不要。
バグってのは687で数値上限云々と書いたとおり、
”C[0]+=1”がawkの整数の精度誤差なし演算可能上限を考慮していないだけ。
どのawkも多分そうだと思うけど、手元の環境下での実行結果↓
C:\>gawk --version
GNU Awk 3.1.7(windows special Nov 24 2009)
C:\>gawk "BEGIN{print 9007199254740990+1}" nul
9007199254740991
C:\>gawk "BEGIN{print 9007199254740991+1}" nul
9007199254740992
C:\>gawk "BEGIN{print 9007199254740992+1}" nul
9007199254740992
実際は(hddやメモリが先に死ぬので)
一行でこれだけ正規表現がhitする事は事実上無いし、
仮に発生しても検索結果が潰れるだけで、気付かない筈。
695 :
688:2012/07/22(日) 13:39:49.16
>9007199254740992
理論上、8192ペタバイトの同じデータ[aaa...]でregexp="."とすれば、発生するな…
IEEE 754の52bit制限だから、これ以上のでかい数字扱うならbig numbert対応のライブラリか,
"bc -q" |& で動かすか、xgawk、dnawkあたり使うべきだなぁ
昔誰かがbignumのawkスクリプト書いて放流していた覚えがあるのだが、
ググッても見つからん。手元にあるのはビット演算のやつだけだわ
いつかそれだけのデータをメモリ上に保持できるマシンを扱ってみたいものだ…
awkってabsとかacosなどの基本的な算術関数が用意されてないんですね
今後も実装されることはないんでしょうか?
パイプでサクッとつないでワンラインで処理するのに重宝してたんですが・・・
代わりとなると、何使うのがよろしいですか?
できればperlは使いたくないです(どうしても好きになれない
absは自分で書けばいいし、acos(x)はatan2(x, √(1.0 - x*x))と書けるから、
どちらも基本的ではないと判断して組み込みじゃないんだと思うけど。
PythonかRubyでいいんじゃない? ワンライナー向きではないけど。
>>696 必要な関数値を計算するだけのプログラムをCで作っておいたら?
700 :
デフォルトの名無しさん:2012/08/03(金) 20:21:59.43
昔それでベクトル演算して遊んだな
Rubyはそこそこワンライナーも書ける感じがする、awkやPerlほどじゃないけどね
Pythonは流石にコード起こさないと辛いことが多いが
awkでmatlabみたいなベクトル演算できるようにしてほしい
awkでクラスを使えるようにしてほしい
awkで全ての魔法少女を救ってほしい
awkさんは魔女
706 :
本田:2012/08/05(日) 07:21:28.03
デバッグ大変過ぎて死ぬる
$ cat witch.awkpp
class Witch {
var spell
method new() { spell = "mahalic mahalita" }
method perform() { print spell }
}
class Samantha : Witch {
method perform() { print "twitch" }
}
BEGIN {
# wife = Witch.new() エラー要因行
wife = Samantha.new()
wife.perform()
}
$ gawk -f awkpp -r witch.awkpp
gawk: -:10: () エラー要因行
gawk: -:10: ^ syntax error
gawk: -:10: () エラー要因行
gawk: -:10: ^ 表現の char '?' は不正です。
size: 656 byte, supports -o -v option. Array A and B can be the same (NEW)
function xagrep( o, re, A, B, this, a, i,k ){
k=0;B[0]=A[0];if(o~"-v"){for(i=1;i<=A[0];i++){if(!match(A[i],re)) B[k+=1]=A[i];}B[0]=k;return k};
if(o~"-o"){B[B[0]+1]=0;for(i=1;i<=A[0];i++){a=A[i];if(i==k){i=i-B[B[0]+1]+1;B[B[0]+1]=k;k=B[0]+2;
while(i<=B[B[0]+1]){B[i++]=B[k];delete B[k++];}i=B[B[0]+1];k=i;B[B[0]+1]=0;}while(match(a,re)){
if(i>k){B[k+=1]=substr(a,RSTART,RLENGTH);}else{B[B[0]+1+(B[B[0]+1]+=1)]=substr(a,RSTART,RLENGTH);
k++}a=substr(a,RSTART+RLENGTH)}}if(i<k){i=k-i;k=B[0]+1;B[0]=i+B[B[0]+1];while(i<B[0])B[i+=1]=B[k+=1];
while(i<k)delete B[i+=1];}return B[0]}for(i=1;i<=A[0];i++){if(match(A[i],re))B[k+=1]=A[i];}B[0]=k;return k;
}
これ以上削れるところ無いかな?
高速化+サイズ優先で、変数はできるだけ使う数を少なくとの条件で
>>708 その3つの条件の優先度がわからんな。
結構同じ部分式があるので変数に入れた方が変数は増えるけど短くなるし
場合によっては速度も速いとかありそうだけどどうなん?
例えばB[0]は特別な用途っぽいけどxとか1文字変数にしてreturnの直前に
書き戻した方が文字数は稼げる。
あと細かいがhoge+=1より++hogeの方が1文字短いとか、いらない「;」が
残ってるとか詰めが甘いところがまだあるね。
以下のようなデータの処理について質問いいでしょうか。
$1に経過時間(時刻)、$2に「速度」があれば$3の数値は速度を、$2$3に
「up a」「down a」などとあればその時刻での行動を示します。
このデータからup、downの場所を求めたいと思います。
つまり、下の例で移動開始からの距離3でup a、距離3.5でup b、という具合です。
経過時間と速度から場所を計算するだけですが。速度を変更するタイミング・
回数は不定、速度データと行動データはともに経過時間順に記録されています。
速度変更をどう扱えばいいのか、ちょっと頭が回りません。
---元データ例---
0 速度 10
50 速度 20
200 速度 25
30 up a
35 up b
40 down a
40 down b
50 up a
70 down a
200 up c
250 down c
---処理後---
3 up a
3.5 up b
4 down a
4 down b
5 up a
6 down a
12.5 up c
14.5 down c
疑問を提示。
$1が常に時刻で$2が速度のときの$3が速度なら、
30 up aのときに30 * 10で300 up aになるんじゃないだろうか。
同じように、70 down aのときに50 * 10 + (70 - 50) * 20で900 down aになるんじゃないだろうか。
$3が速度(単位時間当たりの移動量)ではなく単位移動量当たりの所要時間なのであれば、
30 up aで30 / 10 = 3、70 down aで50 / 10 + (70 - 50) / 20 = 6になるんだけどね。
実装してみた。速度が途中に出てきてもいいようにposを毎回計算するから効率悪いけど。
--
BEGIN {
sCount = 0;
}
$2 == "speed" {
sTime[sCount] = $1;
sSpeed[sCount] = $3;
++sCount;
next;
}
{
pos = 0;
for (ic = 1; ic < sCount; ++ic) {
if (sTime[ic] > $1) break;
pos += (sTime[ic] - sTime[ic - 1]) / sSpeed[ic - 1];
}
pos += ($1 - sTime[ic - 1]) / sSpeed[ic - 1];
print pos, $2, $3;
}
>>711 すみません、前者ですね。なんだろう、恥ずかしい。
>>712 なので、アクション部の / を * に変えればよさそうです。
お二方、ありがとうございます。
awkにかわる同等のものあります?
python
良いですよ
はい
“任意の記号”を含んだシェル変数をawkに渡すことは可能ですか?たとえば
[user@localhost ~]$ var='hoge'
[user@localhost ~]$ echo "hoge" | awk -v var="$var" '
$0 ~ var {print var}
END {print var}
'
hoge
hoge
ここで、varに$を含ませると
[user@localhost ~]$ var='hoge$fuga'
[user@localhost ~]$ echo "hoge" | awk -v var="$var" '
$0 ~ var {print var}
END {print var}
'
hoge$fuga
とうまくマッチしませんでした。var自体は渡されているはずですが、何が原因でしょうか?
>>720 いちぎょうめのひだりがわの var は、ひょうかのさいに
せいきひょうげんへのかたへんかんがおこなわれる。
$0 ~ /hoge$fuga/ {print "hoge$fuga"}
END {print "hoge$fuga"}
めたもじとなってしまうものは、じぜんあるいはこーどのなかで
えすけーぷするひつようがある。
~(チルダ)の右辺は正規表現として解釈されるから、"hoge" ~ /hoge$fuga/ でマッチするわけがない。
逆に寧ろ、"hoge$fuga" ~ /hoge/ ならマッチする。
>>720 >721も>722もどちらも原因。やりたいことをよく整理しよう。
724 :
720:2013/02/06(水) 15:09:21.72
すいません、echo "hoge"ではなくecho "$var"でした。
ただ、結果は
>>720と同じです。
要は入力ファイル内の「メタ文字込みの任意の文字列」を、別の「メタ文字と改行込みの任意の文字列」で置換する、
というのをメタ文字のエスケープ等の面倒な処理をせずにサクッとやりたいのですが、できますか?
ムリ
予め「メタ文字と言っても $ しか出てこない」とか判ってるなら大したこと無いけど
一般化すればするほど面倒になる
726 :
720:2013/02/07(木) 22:14:56.21
>>725 やはりそうですか。
今までこういった処理はsedでしこしこエスケープしてやってたんですが、いい加減面倒になったので、
たとえばfgrepみたいに正規表現をオフにして処理する方法はないかと探しているんですが、
awkでは無理ですか・・・。
>>726 単に一致なら正規表現なんか使わずに比較すればいいじゃん。
fgrepで事が足りるのならawkからfgrepを起動すればいいじゃん。
>>726 fgrepなら index()関数じゃないの?
729 :
720:2013/02/09(土) 15:32:27.55
>>727 >単に一致なら正規表現なんか使わずに比較すればいいじゃん。
意味が分からないんですが、awk上の話ですよね?
>>728 index()の引数は文字列だから、これをうまく使えば目的の処理ができる・・・のかな?
でもなんかawkでごちょごちょやるより、メタ文字をエスケープする前処理をかますなり
何なりしたほうが素直な気がしてきた・・・。たとえばこんな感じで
$ var='hoge$fuga'
$ var2=$( echo "$var" | sed 's/\$/\\\\$/g' ) ←エスケープ処理
$ echo "$var" | awk -v var="$var2" '
$0 ~ var {print var}
END {print var}
'
hoge\$fuga
hoge\$fuga
730 :
デフォルトの名無しさん:2013/02/09(土) 17:49:52.25
/bin/shでごちょごちょやるのが好みなら、awkもfgrepも使わず、case文でやりゃいいんじゃないの。
>>729 文字列の比較は等号でできるって認識はないの?
>729
いや、その方法でも結局 ' はエスケープが必要でしょ。
ダイレクトにシェル変数に入れる方法か、
ファイルなどに吐き出しておく方法の方が安定。
まぁそれでも改行とか制御文字入れられるともにょる場合があるけどな。
そこまでめんどくさくなったらperlとかrubyとか使った方が楽だぞw
何で gawk -f とか使わずワンライナーに拘るのかねぇ
736 :
デフォルトの名無しさん:2013/03/11(月) 10:05:12.56
#
# text converter ( Mac to MS-DOS on Windos/MS-DOS machine)
# convert CR to CR+LF
#
BEGIN{ RS = "\r" }
{ print }
737 :
デフォルトの名無しさん:2013/03/15(金) 08:05:25.28
#
# Line(行数)を数える
#
END { FNR }
738 :
デフォルトの名無しさん:2013/03/20(水) 19:07:17.00
# text to html converter
# usage: awk -f txt2htm.awk infile1.txt > outfile2.html
BEGIN{
print("<html>"); print("<head>")
print("<titile> My favorite URLs </titile>")
print("</head>"); print("<h1> </h1>"); print("<body>");
}
/^[:space:]*http/ { print "<A HREF=\""$1"\">"$1"</A><BR>"}
END{
print("</body>")
print("</html>")
}
739 :
UNIX(LF) to DOS(CR+LF) conversion:2013/03/21(木) 21:15:00.86
awk 1 infile1 > outfile2.txt
# awk -f add.awk
BEGIN {
s1 = "323524855"
s2 = "4972560"
reverse(a2, s2)
size = reverse(a1, s1) # s1 > s2
carry = 0
for(k = 1; k <= size; k++) { # s1 > s2
d = a1[k] + a2[k] + carry
if(d >= 10) {
e[k] = d - 10
carry = 1
} else {
e[k] = d
carry = 0
}
}
if(carry == 1) {
e[k] = 1
size = k
}
g = produce_string(e, size)
printf("%s + %s = %s\n", s1, s2, g)
printf("%f\n", s1 + s2)
exit
}
#
>>740のつづき
function reverse(a, s, k, i) {
k = 1;
size = length(s)
for(i = size; i >= 1; i--) {
a[k++] = substr(s, i, 1)
}
return size
}
function produce_string(a, size, i) {
g = ""
for(i = size; i >= 1; i--) {
g = g a[i]
}
return g
}
function produce_string(a, size, g, i) {
743 :
grepをawkで:2013/03/22(金) 13:32:02.74
# usage: awk -f grep.awk char1 file1 file2
BEGIN{
pattern = ARGV[1]
ARGV[1] = ""
}
$0 ~ pattern {print($0" File name=" FILENAME)}
$ echo 10 20 30 | awk '{for(i=0;i<4;)print _$++i}'
10
20
30
_$++iでも$++iでもどちらでもいけるのですが、アンダースコアが付いて何故大丈夫なのでしょうか?
すいません、わかりました
空の変数_と$++iの結果が一緒になってただけなんですね
単に式を並べると文字列連結になる、の罠か
保守
てか半年近く書き込みが無かったか
4.1.1ってもうリリースされたの?
とあるgawkスクリプトの先頭で
{last_hoge=hoge; hoge=$ 3}
ってやってるんだけど、
hoge=$ 3はhoge=$3の間違い? それともこういう記法がある?
>>749 $ は演算子だから、a=b+1をa = b + 1と書くようなものかな。
ええー 演算子だったのかあ。衝撃の事実
演算子だから、変数でもいいよ。
式が書けるね。
$ は一番優先順位が高いから、かっこで括らにゃいかんが。
今はじめて知った。haskellの$は演算子だって知ってたけど、awkでも演算子だったんだね。
そして半年近く書き込みが無かった
いやawkスレなんて普段はそんなに話題ないだろ
質問させてください
今ディレクトリ内のファイルの名称とサイズのリストを作りたいと思っています
コマンドとしてはls -lを実行していますがこれをさらにawkにパイプしています
ただしファイル名にスペースが含まれているため以下のような苦肉の策をとっておりますが
ls -l | awk '{print $5 "\t" $9$10$11$12$13$14$15$16$17$18$19}'
10個以上で区切られてる可能性もあるため根本的な対応をしたいと考えていますが
よい案はありますでしょうか
# ファイル名に「"」が含まれていたら知らね。
ls -Ql |awk '{split($0, foo, "\x22"); print $5 "\t" foo[2]}'
Qオプションは勉強になった
ls -l|awk '{s=$5;for(i=1;i<9;i++)$i="";print s"\t"$0}'
¥034 は ” (半角)
¥035 は # (半角) でおkですか?
どちらも非可読文字ですね。そしてそうなるとスレ違い。
awkと絡むのなら具体的にどうぞ。
Terastationのファイル・ホルダ名に使うとファイルレプリケーションでエラーが起こる文字があって、それを変換するバッチを生成する時にこのマイナー言語が大活躍した。
約80万件のファイルホルダ名から抽出するのに10分程度だった。