awkについて語るスレ $2
■ このスレッドは過去ログ倉庫に格納されています
0001デフォルトの名無しさん
2007/02/23(金) 23:55:42三人の碩学が生み出したスクリプト言語AWKについて語るスレ
◆ 前スレ
awkについて語るスレ
http://pc10.2ch.net/test/read.cgi/tech/1023556171/
◆ 関係スレ
シェルスクリプト相談室
http://pc10.2ch.net/test/read.cgi/tech/1112553783/
AWKでCGI
http://pc10.2ch.net/test/read.cgi/php/1171804314/
【sed】シェルスクリプト総合@LINUX Part2【awk】
http://pc10.2ch.net/test/read.cgi/linux/1154578200/
◆ 参考
The AWK Programming Language (Brian Kernighan):
ttp://cm.bell-labs.com/cm/cs/awkbook/index.html
GAWK (GNU Projedt):
ttp://www.gnu.org/software/gawk/
0348デフォルトの名無しさん
2010/03/22(月) 18:01:580349デフォルトの名無しさん
2010/03/22(月) 18:25:10なにをしたいのかよくわかんないんだけど。
> 文字列中の全角文字を半角文字に変える華麗な方法を模索しています。
華麗なのはtrコマンドを使う方法。ただtrがマルチバイトをうまく扱ってくれるか
どうかはこころもとない。
Perlならtrを、Rubyなら文字列クラスのtrメソッドを、
Pythonならstringモジュールのmaketrans関数と文字列のメソッドtransleteを使う、
という手がある。
awkないし(tr以外の)古典的なツールで華麗にやる方法はないと思う。
0350デフォルトの名無しさん
2010/03/24(水) 17:11:16全角半角変換は ASC()
半角全角変換は JIS()
0351デフォルトの名無しさん
2010/03/25(木) 08:34:111. EUC-JPにして(nkfとか)kakasi で、戻す
2. それだったら最初から、nkf -Z
3. gawk前提で、文字毎に処理(LANGを指定して子プロセス起動)
awkの中で閉じてやるのはめんどくさそう
0352デフォルトの名無しさん
2010/03/29(月) 23:34:27system(cmd) を使うと、アンチウィルスソフト(kaspersky)の
アプリケーション履歴にバッチファイルが登録されるのを発見。
close(cmd) しても同じ。
while(cmd|getline>0){}
で代用すると残らなくなった。??
0353デフォルトの名無しさん
2010/05/13(木) 00:22:57http://www.cnn.co.jp/world/AIC201005120004.html
テヘランで、ブルカを着て入出国する時って、顔のチェックどうするんだろう。
他人や男でもばれないの?
0354デフォルトの名無しさん
2010/05/13(木) 00:23:49誤爆スマン
0355デフォルトの名無しさん
2010/05/14(金) 13:38:240356デフォルトの名無しさん
2010/05/18(火) 10:51:40下のような出力が有った場合、例えば
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」だけを抜きたい場合記述が大変になります。
何か良い方法は無いものでしょうか?
0357デフォルトの名無しさん
2010/05/18(火) 11:01:32区切りの空白が$5のあったところだけ2個になるのが気にならなければ、
ls -al | awk '{$5 = ""; print}'
とすればよい。
空白2個を修正するならこうする。
ls -al | awk '{$5 = ""; print $0}' | awk '{$1 = $1; print}'
0358デフォルトの名無しさん
2010/05/18(火) 11:03:15ls -al | awk '{$5 = ""; print}' | awk '{$1 = $1; print}'
0359デフォルトの名無しさん
2010/05/18(火) 11:07:030360デフォルトの名無しさん
2010/05/18(火) 11:34:06$1=$1で代入してやると、$1, $2, ...を空白1個でつないだものが$0に代入されるので、
空白2個だったところが空白1個になる。
0361デフォルトの名無しさん
2010/05/18(火) 11:35:04空白2個なので$0を再構成すると空白1個区切りになる
0362デフォルトの名無しさん
2010/05/18(火) 12:21:12非常に解りやすいご説明、ありがとうございます。
なるほど代入することで解決するんですね。
勉強になりました。
0363デフォルトの名無しさん
2010/05/18(火) 15:08:38$1ってFSで区切られた一つ目だよね?
なんでそれ自身を自分に代入したらスペースが消えるん?
0364デフォルトの名無しさん
2010/05/18(火) 15:27:35$0の再構成とはいったんばらした$1,$2,...をOFSを挟んで
つなげ直すってことなので、何で区切られていたかは
保存されない。
0365デフォルトの名無しさん
2010/05/18(火) 15:41:56>$1=$1で代入してやると、$1, $2, ...を空白1個でつないだものが$0に代入される
って約束事を覚えておけってことかい?
0366デフォルトの名無しさん
2010/05/18(火) 15:42:39% echo a b | gawk '{OFS="-";$1=$1;OFS="=";print}'
a=b
再構成は$1=$1をやってすぐじゃなくて、次に$0が使われるとき、ってこと
なのかな?
0367365
2010/05/18(火) 16:27:59http://www.kt.rim.or.jp/~kbk/gawk-3.1/gawk.html
警告: 一部のバージョンのawkは NFを減じたときに$0の再構築を行わない。
結局のところ、awkにレコード全体の再構築を強制したときにはその時点で
フィールドの値とOFSが使われる。再構築を行うためには、何らかの無害な
代入を行う:
$1 = $1 # force record to be reconstituted
賢くなった。あんがと。
0368デフォルトの名無しさん
2010/05/18(火) 16:46:580369デフォルトの名無しさん
2010/05/19(水) 22:24:520370デフォルトの名無しさん
2010/05/24(月) 09:55:14勉強になった。
0371デフォルトの名無しさん
2010/05/24(月) 15:25:460372デフォルトの名無しさん
2010/05/29(土) 04:53:07E-mail:
内容:
cygwinだと
% cut -f1 -d, hoge.csv
より
% awk -F, '{print $1}' hoge.csv
の方が速かった。
#実行時間ね
#Perl?シラネ
0373デフォルトの名無しさん
2010/06/07(月) 11:45:38sed -e 's/,.*//'でもawkと同じくらいだから、cutの実装が遅いんだね。
cutが無駄にオプション多い所為じゃない?
0374デフォルトの名無しさん
2010/06/07(月) 12:04:05hoge.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
0375デフォルトの名無しさん
2010/06/07(月) 12:22:48fgetc()とfgets()で時間を較べたときにfgetc()の方がずっと遅かった記憶がある。
0376デフォルトの名無しさん
2010/09/13(月) 14:14:54そのページがwell-formedか極悪かは私にとってどうでもよく、単に内容を得たいだけなので、文末まで処理し終えて欲しいのです。
どうにかならないでしょうか。
0377デフォルトの名無しさん
2010/09/25(土) 14:55:22アクションをヒアドキュメントで書く事は出来るでしょうか。
0378デフォルトの名無しさん
2010/09/27(月) 14:57:18データが
|1|aaa|
|2|bbb|
|3|ccc|
などとなっているとき
aaa
bbb
ccc
を取り出そうとして
awk 'FS="|"{print $3}' ファイル名
としたんですが、1行目だけがうまくとれません。
データファイルの1行目を空行にすれば解決できないことはないんですが、
空行を入れ忘れてしまう懸念があります。
どうすればいいんでしょうか?
0379デフォルトの名無しさん
2010/09/27(月) 15:01:460380デフォルトの名無しさん
2010/09/27(月) 15:08:38>>379
どうもありがとうございました。
0381デフォルトの名無しさん
2010/09/27(月) 18:42:12下記サイトでは、17番目まで普通に指定できるような事が書いてあるけど、
http://tounderlinedk.blogspot.com/2010/08/gensub-n-awk.html
gensub(pattern,"\\10","g",$2) とかくと
\\1(マッチ箇所)と0(文字)として解釈されちゃって上手くいなかい。
シェルスクリプト風かと思って、\\{10} も試したけどダメダッター。
GNU Awk 3.1.5です。
0382381
2010/09/27(月) 19:00:47実装によって違うのかなあ
パターンを動的に生成してマッチさせようとしてるから結構困る(´・ω・`)
http://www.linux.or.jp/JM/html/GNU_gawk/man1/gawk.1.html
0383デフォルトの名無しさん
2010/09/27(月) 19:04:47マニュアルには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';
なんてやってる。
0384デフォルトの名無しさん
2010/09/27(月) 19:08:030386デフォルトの名無しさん
2010/09/27(月) 21:27:29なんでそこのひとは16までできたんだ?
0387デフォルトの名無しさん
2010/09/28(火) 00:32:520388デフォルトの名無しさん
2010/09/28(火) 03:15:24記念パピコ。
0389デフォルトの名無しさん
2010/09/28(火) 03:41:50気付いたらperlばっかりやっててawkすっかり忘れてしまったなぁ
今はperl捨てて専らpythonやってるけどawkもいいよね
0390デフォルトの名無しさん
2010/09/28(火) 09:40:13手軽であるにも関わらず、結構高度な処理もガリガリ書けるから好き。
Cとシェルスクリプトが好きだから、文法的にもしっくり来る。
上位互換のPerlも大好き。
0391デフォルトの名無しさん
2010/09/28(火) 14:37:590392デフォルトの名無しさん
2010/09/28(火) 14:52:08どれでも好きなのを選べ
1. xgawkを改造
2. エラーになるXMLを事前に修正してwell-formedにしてから食わせる
3. xgawkは捨てて別の言語、ライブラリを試す
0393デフォルトの名無しさん
2010/09/28(火) 17:23:080394デフォルトの名無しさん
2010/10/01(金) 11:21:26シェルスクリプト > awk >>> perl >>>>> python >>>>> ruby >>> haskel etc.
となるだろうな。
シェルスクリプトはシェル依存な部分が多く、perl ほど高機能なものも要らない。
そんな時、小さな端末でもスマートに動いてくれる awk にちんこ勃つ。
>>389
言語に捨てるも拾うもないよ。その時々に都合の良いものを組み合わせて使うのがUNIX的な発想。
0395デフォルトの名無しさん
2010/10/01(金) 15:33:40「一発やろう」ですね!
0396デフォルトの名無しさん
2010/10/09(土) 04:40:48これなら俺でも挫折しなくてすみそう
0397デフォルトの名無しさん
2010/10/09(土) 04:57:140398デフォルトの名無しさん
2010/10/21(木) 20:16:46/ー/{print}
を実行すると
awk:
awk: ^ 正規表現が終端されていません。
awk: 致命的: [ または [^ が対応しません。: /[/{print}/
のエラーになってしまいます。
ーの2バイト目が[なせいだと思いますが、どう対応したらいいでしょうか?
入力ファイルはsjisで書かれていて、文字コード変換はできません。
0399デフォルトの名無しさん
2010/10/21(木) 20:55:41環境の問題なんだから、実行環境くらいまともに書けよ。
0400デフォルトの名無しさん
2010/10/21(木) 21:38:24gawk を使う
0401デフォルトの名無しさん
2010/10/21(木) 22:52:57/bin/awkはシンボリックリンクで、実体はgawkでした。
0402デフォルトの名無しさん
2010/10/21(木) 23:49:35--help 嫁
0403デフォルトの名無しさん
2010/10/22(金) 01:41:070404デフォルトの名無しさん
2010/10/22(金) 02:19:300405398
2010/10/22(金) 07:32:34/\x81\[/{print}
0406デフォルトの名無しさん
2010/10/22(金) 09:41:36根本的な解決になってないけどねぇ。
0407デフォルトの名無しさん
2010/10/22(金) 13:52:100408398
2010/10/22(金) 19:55:530409デフォルトの名無しさん
2010/10/22(金) 20:03:18今あるのかどうか知らないけど。
0410デフォルトの名無しさん
2010/10/22(金) 20:28:38$ echo 'てすと' | gawk '/[ぁ-ん]/ { print length($0) }'
3
UTF-8ロケールでしか試してないけど
cygwinでも大丈夫
0411デフォルトの名無しさん
2010/10/23(土) 01:29:00gawkでいいかな
0412399
2010/10/23(土) 06:55:10問題は解決したのかもしらんが、一応。
以下2つのWin用バイナリは問題ないので、ソースもらってLinux上でコンパイルしてみたら?
ttp://gnuwin32.sourceforge.net/packages/gawk.htm
ttp://www.kt.rim.or.jp/~kbk/gawk-3.1/
0413398
2010/10/23(土) 10:53:14これにしたらsjisでも動くようになるのでしょうか?
0414デフォルトの名無しさん
2010/10/23(土) 12:27:19少なくとも自分が試した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とかにすればいいのかと思ったが、ロケール変更自体がうまくいかなかったわ。
困ってる事があるなら、最終的に何がしたいか言ったほうがいいよ。
0415398
2010/10/23(土) 12:40:31困っていたことは405で解決したので大丈夫です。
今は「根本的な解決」に興味があったのでお聞きした次第です。
0416初心者
2010/11/04(木) 22:14:100417デフォルトの名無しさん
2010/11/04(木) 23:14:10初心者だからマルチが許されるとでも思ったか?
0418初心者
2010/11/05(金) 06:32:09知りませんでした。
0419デフォルトの名無しさん
2010/12/15(水) 01:54:35length みたいなのは無い?
0420デフォルトの名無しさん
2010/12/15(水) 02:27:500421デフォルトの名無しさん
2010/12/15(水) 02:42:46と思ったら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.
0422デフォルトの名無しさん
2010/12/15(水) 04:20:37作成するときに数えればいいんじゃね?
0423デフォルトの名無しさん
2010/12/15(水) 08:40:150424419
2010/12/25(土) 03:12:23って事が分かりますた
0425デフォルトの名無しさん
2010/12/28(火) 11:29:350426デフォルトの名無しさん
2010/12/28(火) 13:55:13翻すとUNIX文化そのものが
まあ、あくまでおれの主観ですがね
0427デフォルトの名無しさん
2010/12/28(火) 15:24:21awk大好きなオイラに喧嘩売るのかw
ウニックス文化最高!(NT系はUNIXのパクリ)
0428デフォルトの名無しさん
2010/12/28(火) 15:28:13全角英字使う奴が awk 大好きだとは到底思えん
0429デフォルトの名無しさん
2011/01/05(水) 23:22:550430デフォルトの名無しさん
2011/01/06(木) 00:22:04BEGIN{
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 [email protected]
BEGIN [email protected]
BEGIN [email protected]
BODY [email protected]
BODY [email protected]
BODY [email protected]
▼gawk -f tes09.awk
BEGIN [email protected]
BEGIN [email protected]
BEGIN [email protected]
ここで、BEGIN句での ARGV[1]="hoge.txt" という代入を本編(?)でも有効にする為
にはどうすればいいでしょうか?
0431デフォルトの名無しさん
2011/01/06(木) 00:31:45質問の趣旨がわからん
0432430
2011/01/06(木) 06:20:53hoge.txtの中身は下記です。
▼
[email protected]
[email protected]
[email protected]
>>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 '・' は不正です。
0433デフォルトの名無しさん
2011/01/06(木) 08:57:49>gawk: tes09.awk:2: ^ 表現の char '・' は不正です。
これは全角スペース
0434デフォルトの名無しさん
2011/01/06(木) 09:12:00>BEGIN [email protected]
>BEGIN [email protected]
コレはgetlineで読んで出力したもの
>BODY [email protected]
>BODY [email protected]
>BODY [email protected]
コレはコマンドで指定したファイルから出力したもの
たとえば
{
print "BODY\t"$0
}
としてやれば明らか
0435デフォルトの名無しさん
2011/01/06(木) 13:46:53コマンドライン引数を追加したいという事ですか。
コマンドライン引数の配列は ARGV ですが、コマンドライン引数の
個数を格納する ARGC という組み込み変数があります。
ARGV配列を追加したら一緒に ARGC を修正してあげないと、awkは配列が
追加された事を認識しません。
BEGIN内でARGV配列を追加した分だけARGCをインクルメントしてあげれば
追加されたARGV配列で指定されたファイルも本文の処理に渡されます。
蛇足としては、
現在処理中のファイル名が格納されている配列 ARGV のインデックスを
示す組み込み変数は ARGIND です。
私のは Win版の gawkm115 です。スクリプト内でARGV/ARGCを操作しても
期待通り正常に動きますよ。
試してみてね。
0436430
2011/01/06(木) 23:56:01>>433
>これは全角スペース
お恥ずかしい限りです(汗) 出勤前に思いつきで試したもので、スレ用に書いた
物をそのままコピってました・・・
>>434
BEGIN句のgetlineではARGV[1]への代入ができているのに、本文では有効に
ならないという事を伝えたかったのです。
0437430
2011/01/06(木) 23:56:17自分の質問を見直してみると全く質問になっていなかったにも関わらずエスパー
してくださってありがとうございます。
ARGCについて理解できました。
BEGIN{
ARGV[1]="hoge.txt"
ARGC=2
}
ARGV[1]=="hoge.txt"{
print "BODY\t"$0
}
こんな感じで意図した通りに出力されました。
おかげさまで今までawkの補助としてshを使ってましたが、awkだけで書ける事が
多くなりました。
引数にワイルドカードを指定して、ARGIND で特定パターンのファイル名の
物のみ処理をするとかできそうですね。
0438デフォルトの名無しさん
2011/01/09(日) 22:38:39My 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せずに実行することは可能でしょうか?
0439デフォルトの名無しさん
2011/01/09(日) 22:54:330440デフォルトの名無しさん
2011/01/09(日) 23:06:13とかではだめでした。
0441デフォルトの名無しさん
2011/01/10(月) 03:54:21なんか " と \ の数がおかしくね?
My Documents\2011\01\09(日)
↓
"My Documents\\2011\\01\\09(日)"
↓
"My Documents\\" year "\\" month "\\" date day
だよな?
0442デフォルトの名無しさん
2011/01/10(月) 11:42:11はい。
\はおっしゃるとおりですが、依然としてだめです。
today.batをコマンドプロンプトから実行すると、
printしてそのtmp.batを実行する438のパターンだと、
ちゃんとcdできて、今日のフォルダに移動するのですが、
system("cd \\"My Documents\\" year "\\" month "\\" date day);
だと、移動せずに終了してしまいます。
なんでだろーな。
0443デフォルトの名無しさん
2011/01/10(月) 12:32:20systemはshで動くっぽいので
rm /cygdrive/c/Documents\ and\ Settings/test.txt
みたいに書くとちゃんと消えるみたい
0444デフォルトの名無しさん
2011/01/10(月) 13:24:47438で書いてるgawkでやりたいことってのはバッチファイルでやってるのと同じこと?
だったら無理。
system() でcdしてもsystem()から返ってきたところで元に戻る。
0445デフォルトの名無しさん
2011/01/11(火) 01:15:490446デフォルトの名無しさん
2011/01/11(火) 09:05:01なるほど。gawk内部ではシステムを実行していても、gawkを出ると、それも終わっちゃうんですね。なるほど。
よくわかりました。ありがとうございます。
0447デフォルトの名無しさん
2011/01/19(水) 02:44:33非効率極まりない
■ このスレッドは過去ログ倉庫に格納されています