- 1 名前:デフォルトの名無しさん mailto:sage [2007/02/23(金) 23:55:42 .net]
- 腐っても鯛? 騏も老いては駑馬に劣る?
三人の碩学が生み出したスクリプト言語AWKについて語るスレ ◆ 前スレ awkについて語るスレ pc10.2ch.net/test/read.cgi/tech/1023556171/ ◆ 関係スレ シェルスクリプト相談室 pc10.2ch.net/test/read.cgi/tech/1112553783/ AWKでCGI pc10.2ch.net/test/read.cgi/php/1171804314/ 【sed】シェルスクリプト総合@LINUX Part2【awk】 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/
- 841 名前:デフォルトの名無しさん [2016/09/27(火) 19:51:11.26 ID:Icjzq3KF.net]
- Cygwin は試してみたけどインストーラに丁重にお断りされたよ。
- 842 名前:822 [2016/09/27(火) 23:10:22.59 ID:eGFFwbsN.net]
- たくさんの情報ありがとうございます。現状でWindowsに拘るなら、Bruce版3.1.7を継続して
使用するか、Cygwin版に乗り換えるか、Windows Subsystem for Linuxで動作させるかの いずれかになりそうですね。 CygwinやWindows7でのWindows Subsystem for Linuxは、どちらも別途インストールが必要 とのことなので、職場の自PCはともかくスクリプト配布先に(スクリプトを動かすためだけに) 導入してもらわないといけないのはちょっと難しそうです。 Cygwinの導入状況とWindows10への切り替え時期の様子を見つつ、しばらくBruce版3.1.7を 使うことにします。
- 843 名前:デフォルトの名無しさん [2016/09/28(水) 07:26:06.87 ID:6NcLFLen.net]
- 実は方法が無いわけではない。シングルバイトモードならできる。でも本当にやりたい?
本当に真剣に必要としているなら、このスクリプトでテスト3をやってみてほしい。 { c = "[\\000-\\177]|[\\340-\\357][\\200-\\277][\\200-\\277]" # print( length($0)); str = $0; print( gsub( c,"0",str)); print; sub(/<tag>/, ""); sub(/<\/tag>/, ""); sub(/hello/, "ABC"); # sub(/.う/, "U"); sub( sprintf("(%s)う",c),"U") print; }
- 844 名前:デフォルトの名無しさん [2016/10/01(土) 22:37:26.49 ID:apxhHWta.net]
- やっぱり klabaster gawk はよく解らない。
$cat u2.awk { print( length($0)) sub(/う/, "U") print; } $LANG=C wine ../gawk64.exe -f u2.awk u2.txt > /dev/null $LANG=ja_JP.EUC-JP wine ../gawk64.exe -f u2.awk u2.txt > /dev/null $LANG=ja_JP.UTF-8 wine ../gawk64.exe -f u2.awk u2.txt > /dev/null gawk64: u2.awk:3: sub(//, "U") gawk64: u2.awk:3: ^ unterminated regexp gawk64: u2.awk:4: sub(//, "U") gawk64: u2.awk:4: ^ unexpected newline or end of string $ UTF-8 で「う」は 3 バイトだから、シフトJISで解釈した結果 その後ろの / もマルチバイト文字の一部になるのだろうか。 いや、UTF-8 で解釈してくれないことに文句を言いたいんじゃないんだ。 UTF-8 で書いてあるのになぜ LANG=ja_JP.UTF-8 の時だけエラーになるのだろう。
- 845 名前:デフォルトの名無しさん [2016/10/02(日) 00:14:27.80 ID:lSw/Qfuv.net]
- この記事を見るかぎりではklabaster以外のWindows版gawkでもダメっぽいです
https://groups.google.com/forum/#!topic/comp.lang.awk/coXxXOpeoXU
- 846 名前:デフォルトの名無しさん mailto:sage [2016/10/08(土) 21:51:54.06 ID:66+5bUgM.net]
- >>748からのレスで、$が演算子だったの? というようなところが気になって
少し調べてみた(調べたというほどの作業はしてないか)。 まず書籍。手持ちの数冊で確認。 『プログラミング言語AWK』(トッパン 初版第7刷) さいごのまとめで演算子一覧に記載。本文中(p8)では「欄は常に$1,$2のように 参照しなくてはいけないと思われているかもしれないが、実は$のあとには,欄の 番号を指し示すための任意の式を書いてもよい」と書かれている。また、p46には 「欄変数」の項に「入力行の欄(field)は,$1,$2から始まって,$NFという名で呼ばれる」 との記述がある。 『sed & awk プログラミング』(アスキー出版局 初版) 旧版。本文中(p212)で「フィールドを参照したいときには、フィールド演算子$を使えばよい」 また(p217)で「フィールドを参照するにはドル記号($)演算子を使う」、Appendix(p471)で 「それぞれのフィールドは、$1ならば最初のフィールドの値を参照し、」と表現されている。 Appendixの演算子一覧に記載。 『AWKを256倍使うための本』(アスキー出版局 初版) Appendixで演算子一覧に記載されているが、本文(p65)で「分解された各フィールドは、 $nという変数(nは、始めのフィールドから順に1,2,3...となる。もちろん即値の代わりに変数を 指定することも可能だ)でアクセスすることができる」とある。他の箇所でも$n変数と書いてある ところがある。p66で「各フィールドを表す$nであるが、なぜこんな名前になっているかご存じだろうか? 実はこれもUNIX文化からきているのだ。UNIXの代表的なシェルであるshやcsh(最近ではkshや tcshかな?)のシェルスクリプトのなかでコマンドラインパラメータを表す変数として$nが使用されて おり(中略)これにあわせてawkで$nが使用されているようなのである」と書いてある。 『AWK実践入門』(技術評論社 初版) >>765にあるように特別な変数として扱われており、リファレンスにも$が演算子で あることの記載がない。 (続く)
- 847 名前:835 mailto:sage [2016/10/08(土) 22:00:44.45 ID:66+5bUgM.net]
- (続き)
ネットの情報。2016.10.8現在。 Gnu Awk ユーザーズガイド/The GAWK Manual/Effective AWK Programming gawkの解説書。バージョン違いがあるようだが、翻訳版で目に留まったもの。 「定数でないフィールド番号」の項で「あるフィールドを参照するために、awk言語での任意の式を `$'の後で使うことができる」と記述されている。「演算子の優先順位」の項では演算子として 並べられている。 man gawk 翻訳版、リナックスコマンドというサイト(www.linux-cmd.com)から。 「入力レコード中の各フィールドの値は、左から $1, $2 等という名前で参照できます。 $0 はレコード全体です。フィールドに値を代入することもできます。フィールドは定数だけでなく、 変数によって参照することもできます。」となっている。演算子のところに記載あり。 AWK Users JP サイト中「awk 基礎文法最速マスター」のページで「特殊変数」の項に$0,$1〜$NFの説明。 フィールド参照の語はない。また、リファレンス的な演算子のまとめはない(?)。 ページ上部に「この文書は書きかけです」とあるので、未整備ということだろうか。 IBM Knowledge Center awkコマンドのページ(www.ibm.com/support/knowledgecenter/ja/ssw_aix_71/ com.ibm.aix.cmds1/awk.htm)では「レコードとフィールドによるファイル処理」の項で 「各フィールドはフィールド変数によって参照されます。レコードの最初のフィールドには $1 変数、 2 番目のフィールドには $2 変数というように、変数が割り当てられます。」との記述。少しうしろの 方、「フィールド変数」の項でも「フィールド変数は、$ (ドル記号) とそれに続く数値または数値式で 指定します。」とある。$が演算子であることの記載はない。 てな感じで、『プログラミング言語AWK』でも「欄変数」という表現があり、誤解しそうな感じはする。 また、256倍本に書いてあるようにシェルスクリプト中のパラメータとして$nがあることから、$nが (特別な)変数として認識されてしまっているのではないか、とも想像する。個人サイトのawkの解説 ページでは、$nという変数にフィールドが代入されると説明しているところもあった。そのように理解して スクリプトを書いてもさして不都合はないだろうな、とは思うが。
- 848 名前:デフォルトの名無しさん mailto:sage [2016/10/08(土) 23:11:50.50 ID:ZMh6U7O9.net]
- 広範な調査乙。Gawkのrefcardでもちゃんとoperatorに含まれているなあ。
演算子と明確に認識していなくても、$の後に式OKと思っていれば差し支えなさそう。
- 849 名前:デフォルトの名無しさん [2016/10/18(火) 23:10:18.54 ID:TQpGgbw6.net]
- gawk4で関数ポインタみたいなもんが追加されましたけど、これlengthとかsubstrの
組込み関数や@loadした自作dllの関数とかにも使えるんですね 案外便利かも @load "hage.dll" BEGIN{ kumi = "length" func = "hagefunc" ng[1] = "substr" print @kumi("ABC") print @func("彡 ⌒ ミ ") print @ng[1]("XYZ", 1, 1) # 配列越しに呼ぼうとしたらsyntax error・・・残念 }
- 850 名前:デフォルトの名無しさん [2016/10/21(金) 17:10:59.85 ID:MQQBNMPM.net]
- >>755
こういう過疎スレで無駄に突っかかってくるやつむかつくんだが死ね
- 851 名前:デフォルトの名無しさん mailto:sage [2016/11/23(水) 00:01:26.03 ID:bt3mTQnz.net]
- >>840
ブーメランかよwww
- 852 名前:デフォルトの名無しさん mailto:sage [2016/11/23(水) 01:18:15.98 ID:noM2Pdp3.net]
- \おはげだー!/
- 853 名前:デフォルトの名無しさん [2016/11/30(水) 02:56:38.28 ID:PeC/aWZc.net]
- imgur.com/a/1WEjn
- 854 名前:C初心者 [2017/02/28(火) 13:18:15.09 ID:Mb8mQo1M.net]
- awkスクリプトをCソースに変換してコンパイルするための「awka」というツールでできるだけ簡単にUTF−8サポートさせる方法を知りたいです。
ネットで散々調べましたがないようです?
- 855 名前:デフォルトの名無しさん mailto:sage [2017/03/02(木) 00:28:53.73 ID:CDxvUfiY.net]
- このスレも10周年か
- 856 名前:デフォルトの名無しさん mailto:sage [2017/03/05(日) 09:28:55.73 ID:EQCsqksH.net]
- >>844
それがあなたの現在の実力だったということです お疲れ様でした
- 857 名前:デフォルトの名無しさん mailto:sage [2017/03/05(日) 14:45:26.28 ID:KmKKYedf.net]
- gawkに対応してるなら大丈夫ってことかな?
asciiしか考えていないなら、ソース全チェック…。 要するに、日本語化するんだろうけど。 全然別の言語変換にちょっと咬んだことがあるんだけど、 製品化しちゃってからダブルバイト考慮してないことがわかって、かなり面倒だった。 とりあえず変換してから、ソース見て直すほうが早かったり(笑 がんばってね。
- 858 名前:デフォルトの名無しさん [2017/03/06(月) 11:39:31.22 ID:FdaYmB9f.net]
- awkで $1,$2...$6 こんな出力を↓下にしたいんだけど どうすればいいですかね?
470230 470290 ↓ 002347 002479
- 859 名前:デフォルトの名無しさん mailto:sage [2017/03/06(月) 12:33:46.83 ID:FW5jfGh1.net]
- GNU awk の asort() を使うとか。
printf '470230\n470290\n' | gawk -vFS= -vOFS= '{ for(i=1;i<=NF;i++){ arr[i]=$i }; asort(arr); for(i=1;i<=NF;i++){ $i=arr[i] }; print }'
- 860 名前:デフォルトの名無しさん [2017/03/06(月) 15:19:43.83 ID:FdaYmB9f.net]
- ありがとう
gawk いれないでなんとかならないかな
- 861 名前:デフォルトの名無しさん mailto:sage [2017/03/06(月) 17:28:40.15 ID:FW5jfGh1.net]
- う〜ん、そうなると awk を使わなくてもいいかな
printf '470230\n470290\n' | while read -r n do echo "$n" | grep -o . | sort -n | tr -d '\n'; echo done
- 862 名前:デフォルトの名無しさん [2017/03/06(月) 19:23:27.89 ID:08XsJPyW.net]
- >>841
だからブーメランとかそういうの関係ないから死ねって言ってんだろカス 死ね
- 863 名前:デフォルトの名無しさん [2017/03/06(月) 19:24:30.15 ID:08XsJPyW.net]
- >>845
粘着が10年位延命しても何もすごくねえよ 突っかかってきたぶちころすぞ雑魚死ね>>841
- 864 名前:デフォルトの名無しさん [2017/03/06(月) 19:26:33.18 ID:08XsJPyW.net]
- >>841
ブーメランとかじゃなくて死ねって言ってんだから死ねボケ
- 865 名前:デフォルトの名無しさん mailto:sage [2017/03/07(火) 08:17:48.93 ID:6Hf5Xh2e.net]
- お疲れ様でした
- 866 名前:デフォルトの名無しさん [2017/03/09(木) 21:48:39.65 ID:0T9qj2kA.net]
- 連想配列で
echo '470230' | awk 'BEGIN{FS=""}{for(i=1;i<=NF;i++){a[$i]++}for(i=0;i<=9;i++){for(j=1;j<=a[i];j++){printf("%s", i)}}printf("\n")}' 002347
- 867 名前:デフォルトの名無しさん mailto:sage [2017/03/10(金) 00:18:57.87 ID:+B1nKlhG.net]
- 既に否定されているがgawk4がもし使えたら
awk '{ORS="";PROCINFO["sorted_in"]="@val_num_asc";x=split($0,a,"");for (i in a)print a[i];print "\n"}'
- 868 名前:デフォルトの名無しさん mailto:sage [2017/03/10(金) 04:05:38.25 ID:wGo6zQ56.net]
- 最近の gawk ならインクルードファイルが用意されてて join とか使えたり
gawk -vFS= -vOFS= -i join.awk '{split($0,a,"");asort(a);print join(a,1,length(a),SUBSEP)}'
- 869 名前:デフォルトの名無しさん [2017/04/04(火) 22:35:43.00 ID:9/WMFGSO.net]
- # gawk4の読込みタイムアウト機能、けっこう便利そう・・・だけどWindowsはCygwin版じゃないと使えない。残念無念。
BEGIN{ PROCINFO["/dev/stdin", "READ_TIMEOUT"] = 180000 print "3分間待ってやる" getline t < "/dev/stdin" if (t=="バルス") { print "ああ…ああ…目があぁぁぁぁぁ〜!" } else { print "時間だ!答えを訊こう!" } }
- 870 名前:デフォルトの名無しさん [2017/09/16(土) 00:02:08.63 ID:lO9EtkAG.net]
- 自作の読込みパーサextensionでgz形式のファイルを食えるようにしてみたけど
パーサは一度にひとつしかロードできない設計らしく(ソースでそうなってた) 同じ読込みパーサ形式のxmlライブラリとは併用できなかった ちょっと使いにくいなあ・・・
- 871 名前:デフォルトの名無しさん [2017/10/09(月) 16:41:58.59 ID:7/rU/a8H.net]
- 4.2.0Betaあげ
- 872 名前:デフォルトの名無しさん mailto:sage [2017/10/16(月) 14:34:21.07 ID:tJ1aGDYb.net]
- ファイルの終端関係の謎のエラーに直面
「何で行末が欠ける?分からん、全然分からんぞ!」 と悶えていたら、 いつの間にかvimの設定が変になっていて、 書いたファイルがデフォで行末に\rが来る ようになっていた。 brew でインストールvimインストールしたとき 妙な設定になったのか? いやねawkのスクリプトで、 空フィールドが\rになったりとか macOSなのに変だなあと思っていたのだが… システム外vim使うときは要注意か。
- 873 名前:デフォルトの名無しさん mailto:sage [2017/10/16(月) 14:41:37.20 ID:tJ1aGDYb.net]
- うぉーっ、林檎のnumbersで書き出したCSVファイルが
DOS改行になっとる…罠だ
- 874 名前:デフォルトの名無しさん mailto:sage [2017/10/22(日) 23:24:45.88 ID:/qEHJ0vm.net]
- お疲れ様でした
- 875 名前:デフォルトの名無しさん [2017/10/22(日) 23:26:23.47 ID:/qEHJ0vm.net]
-
- 876 名前:href="../test/read.cgi/tech/1172242542/755" rel="noopener noreferrer" target="_blank">>>755
普段話題なく3年も続こうがべつにすごくないね []- [ここ壊れてます]
- 877 名前:デフォルトの名無しさん [2017/12/09(土) 10:00:30.84 ID:/kecouyU.net]
- BEGIN{for(i=1;i<=10000000;i++){printf "%08d", i > "test" } close("test)} の実行にかかる時間を
4.1.4と4.2.0で比較すると、4.2.0のほうが倍近く速くなってるね fwriteのロックがどうたらの影響なんだろうけど
- 878 名前:デフォルトの名無しさん mailto:sage [2017/12/12(火) 21:01:15.07 ID:zxiueT/o.net]
- 懐かしいなぁ。
AWKは自由に現実的な限度はあるけど、書いてて楽しい言語だった。
- 879 名前:デフォルトの名無しさん [2018/01/08(月) 11:00:30.57 ID:szpKYJOz.net]
- お疲れ様でした
- 880 名前:デフォルトの名無しさん [2018/01/12(金) 00:18:25.22 ID:8Bbkgawk.net]
- IDがgawkなので来ました
- 881 名前:デフォルトの名無しさん mailto:sage [2018/01/17(水) 10:09:56.59 ID:MoHAEd1l.net]
- AWKって基本的にUnicodeには対応してるんだよね。
GNUにしろBSDにしろ。
- 882 名前:デフォルトの名無しさん mailto:sage [2018/01/17(水) 17:52:56.47 ID:MoHAEd1l.net]
- 置換函数の第二仮引数に[バックスペース][置換対象の文字列]みたいにしたい時は
gsub(/foo/, "\\\\&", $n) ってしないといけないんだね。 gsub(/foo/, "\\bar", $n) が foo -> \bar だったんで foo -> \foo は gsub(/foo/, "\\&", $n) でいいと思って半時程嵌った。
- 883 名前:デフォルトの名無しさん mailto:sage [2018/01/18(木) 07:25:24.80 ID:eRgrS92p.net]
- >>863
それ勧告に従っただけだと思うが。 www.ietf.org/rfc/rfc4180.txt
- 884 名前:デフォルトの名無しさん [2018/03/09(金) 13:30:21.59 ID:Yd19z7Tx.net]
- ある行に 20 と 34 とはいってる
この行ごと除外したいけど・・・
- 885 名前:デフォルトの名無しさん mailto:sage [2018/03/09(金) 14:33:06.31 ID:X3i0O3oy.net]
- grep -v ' 20 と 34 '
- 886 名前:デフォルトの名無しさん [2018/03/09(金) 21:38:00.87 ID:3i0y1Him.net]
- こうかな
gawk "$0!~/20|34/{print}"
- 887 名前:デフォルトの名無しさん mailto:sage [2018/03/09(金) 23:45:36.30 ID:Ejthnyow.net]
- AWK プログラムの基本構造となっている「パターンとアクションの対」のうち、
アクションが省略されている場合は入力行がそのまま出力される。 またパターンが単一の正規表現である場合は、その正規表現と $0 との照合が行われる。 gawk '!/20と34/' gawk '!/20|34/'
- 888 名前:デフォルトの名無しさん [2018/03/10(土) 21:39:17.88 ID:NqpdHf3N.net]
- こぴぺしてやってみたけど 両方消えちゃうんだよね
20 と 34があった場合 出力しない 片方でもあれば 出力する awk '!/01 / && !/03 /' これも両方消えてる・・
- 889 名前:なんか日本語がおかしいな。 mailto:sage [2018/03/11(日) 06:07:55.06 ID:rsmr5+n0.net]
- >>877
「20 と 34 を両方含む時だけ出力しない。片方だけの場合は出力する。」 そう言いたいのか? gawk '!(/20/&&/34/)'
- 890 名前:デフォルトの名無しさん [2018/03/11(日) 10:58:35.24 ID:tN+YLJlR.net]
- ありがとう
()はきがつかなかった・・
- 891 名前:デフォルトの名無しさん [2018/05/23(水) 20:10:48.40 ID:Au5e7VGg.net]
- 僕の知り合いの知り合いができたパソコン一台でお金持ちになれるやり方
役に立つかもしれません グーグルで検索するといいかも『ネットで稼ぐ方法 モニアレフヌノ』 0VDE5
- 892 名前:デフォルトの名無しさん [2018/06/08(金) 22:00:41.48 ID:W8HYHVfd.net]
- split関数より$0へ代入したほうが速いage
- 893 名前:デフォルトの名無しさん mailto:sage [2018/06/27(水) 16:43:15.93 ID:tzYH0Nnw/]
- そんなわけないw
- 894 名前:デフォルトの名無しさん [2018/07/04(水) 22:29:02.55 ID:gFgZc5FG.net]
- 02P
- 895 名前:デフォルトの名無しさん mailto:sage [2018/07/05(木) 16:52:56.22 ID:AeL6VB/V.net]
- 0VDE5
- 896 名前:デフォルトの名無しさん mailto:sage [2018/09/11(火) 09:26:39.50 ID:196Ukd9B.net]
- シェルスクリプト書いててどうしようもないときだけ使ってる
- 897 名前:デフォルトの名無しさん mailto:sage [2018/12/02(日) 13:44:27.64 ID:jISJOvCb.net]
- AWKって重いと勝手に思ってたけど下手にシェルで制御構文作るより早いね
尤もWSLでやってるのでforkの時間とかそういう問題かもしれないが。
- 898 名前:デフォルトの名無しさん mailto:sage [2018/12/02(日) 14:22:41.55 ID:Bx+z5yQP.net]
- >>886
重いと言ってもC比だからな。 今時の超大富豪言語PythonやRubyとなら同程度でもおかしくはない。 Cygwinのshが重かったのはご存じの通りforkが原因だ。 気になるならVirtualBox等でlinux環境を構築してその上でテストしてみればいい。
- 899 名前:デフォルトの名無しさん [2018/12/22(土) 02:10:55.36 ID:V7w17XLB.net]
- gawk4にて配列の配列に存在する全要素数を
カウントする関数を作ったんですが、 もっと早いコードにならないでしょうか? どなたかヒントをください。お願いします。 function count_array(arr, n, i) { for (i in arr) { if (isarray(arr[i])) count_array(arr[i], n); else n[0]++; } return n[0]; }
- 900 名前:デフォルトの名無しさん mailto:sage [2018/12/22(土) 02:57:46.65 ID:kZtDaodg.net]
- length(arr) でダメなの?
- 901 名前:デフォルトの名無しさん [2018/12/22(土) 20:12:58.98 ID:VPYzPSxJ.net]
- 886です。
ダメなんです。 BEGIN { a[1] = 1; a[2][1] = 21; a[2][2] = 22; a[3] = 3; a[4][1][1] = 411; a[4][2] = 42; a[4][3][2][1] = 256; for (i = 0; i < 9; i++) b[i] = i; c["foo"]["corge"] = "grault"; c["foo"]["bar"] = "garply"; c["baz"]["corge"] = "waldo"; c["baz"]["quux"] = "fred"; print "length(a) = " length(a); print "length(a) = " length(b); print "length(a) = " length(c); print "count_array(a) = " count_array(a); print "count_array(b) = " count_array(b); print "count_array(c) = " count_array(c); } length(a) = 4 length(b) = 9 length(c) = 2 count_array(a) = 7 count_array(b) = 9 count_array(c) = 4 再帰を使う以外に方法があれば、 と思い質問した次第です。
- 902 名前:デフォルトの名無しさん [2018/12/22(土) 21:58:49.47 ID:b6CiPLFa.net]
- 要素を追加するときに
ノード毎に集計値が必要ならそれぞれのノード毎の集計値を保存しとけばいい そうすれば集計しなおす必要ない 超速いハズ 集計しないからな
- 903 名前:デフォルトの名無しさん [2018/12/22(土) 22:19:10.29 ID:b6CiPLFa.net]
- こういった集計値がほしいのは分かる
aho(9) ┣aho1(5) ┃┣aho11(3) ┃┃┣aho111(1) ┃┃┗aho112(1) ┃┗aho12(1) ┗aho2(3) ┣aho21(1) ┗aho22(1) lengthでは、きっとこんな感じでしかとれない aho(2) ┣aho1(2) ┃┣aho11(2) ┃┃┣aho111(n/a) ┃┃┗aho112(n/a) ┃┗aho12(n/a) ┗aho2(2) ┣aho21(n/a) ┗aho22(n/a)
- 904 名前:デフォルトの名無しさん mailto:sage [2018/12/22(土) 23:48:44.15 ID:omdhpVTe.net]
- >>890
lengthは、配列aの要素に配列があると要素としての配列の 中の要素数まではカウントしない、やりたいのは要素としての配列に 含まれる要素もカウントしたい、ということか。 function count_array2(arr, cnt, i) { n=0; for (i in arr) { if(isarray(arr[i])){ cnt+=length(arr[i]); } else n++; } return n; } だと a[1] = 1; a[2][1] = 21; a[2][2] = 22; a[3] = 3; a[4][1][1] = 411; a[4][2] = 42; a[4][3][2][1] = 256; a[4][3][3][2] = 257; みたいなのでうまくいかない(1番目と2番目の添え字(?)が同じ)。 arr[i][j]...と続ければ(最初にlength(arr)で続ける深さを決めて) いけるように思うが、だったら再帰するのが素直か。
- 905 名前:デフォルトの名無しさん [2018/12/23(日) 00:54:43.50 ID:quoNoaXg.net]
- 886です。889さんこんな感じでしょうか?
BEGIN { addnode(a, "1-1", "start"); addnode(a, "1-2", "done"); addnode(a, "1-3", "result"); addnode(a, "1-4", "print"); addnode(a, "2", "count"); addnode(a, "3-1-1", "return"); for (i in a[1]) print "a[1][" i "] = " a[1][i]; print "a[2] = " a[2]; print "a[3][1][1] = " a[3][1][1]; print "\n_ele_sum = " _ele_sum; } function addnode(arr, i, val, p) { ct = split(i, list, "-"); switch (ct) { case 1: arr[list[1]] = val; break; case 2: arr[list[1]][list[2]] = val; break; case 3: arr[list[1]][list[2]][list[3]] = val; break; default: } _ele_sum++; } a[1][1] = start a[1][2] = done a[1][3] = result a[1][4] = print a[2] = count a[3][1][1] = return _ele_sum = 6
- 906 名前:デフォルトの名無しさん [2018/12/23(日) 01:05:13.25 ID:quoNoaXg.net]
- 886です。
pとか関係ないパラメータ入れてしまってごめんなさい。 addnode(a, "1-5-1", "connot"); これができません。 a["5"]がスカラーだと言っています。
- 907 名前:デフォルトの名無しさん [2018/12/23(日) 01:15:19.57 ID:quoNoaXg.net]
- 訂正a["1"]["5"]がスカラーの文脈だと言っています。でした
- 908 名前:デフォルトの名無しさん [2018/12/23(日) 01:41:32.84 ID:quoNoaXg.net]
- 886です
for (i in a[1]) print "a[1][" i "] = " a[1][i]; でa[1][5][1]が引っかかっていたようです。 自爆でした。すみません。
- 909 名前:デフォルトの名無しさん [2018/12/23(日) 02:59:04.54 ID:quoNoaXg.net]
- 886です。
親ノード毎?に保存する方法がまだわかりませんが、 明日以降考えます。 みなさん、ご協力ありがとうございました。
- 910 名前:デフォルトの名無しさん [2018/12/23(日) 08:49:07.73 ID:S8HMq/6c.net]
- gawk4でとにかく速いのが良いならcで拡張関数作るのが良いかと(反則?)
flatten_array_typed関数(4.1.4はflatten_array関数)でawk_flat_array_t構造体のメンバ変数countに要素数が入りますので 要素がAWK_ARRAYなら再帰するように処理すれば出来上がり APIの使い方は extension\rwarray.cとか https://www.gnu.org/software/gawk/manual/html_node/Flattening-Arrays.html#Flattening-Arraysを参考に gawkだけでやる場合、もし配列の要素数が10万とか100万あるのなら、関数の引数を出来るだけ減らして 関数内からグローバル変数を直接参照したほうが速くなると思います
- 911 名前:デフォルトの名無しさん [2018/12/23(日) 11:20:10.63 ID:qffc/3mK.net]
- もともと添え字がすべて文字列で保存する仕様というのはしってはいたが
多次元配列はaho[i,j]という形式にして工夫して使えということらしいな awkで多次元配列なんか使ったことないから知らんかったわ とういワケでにその形式で多次元配列をlengthでとると>>888で取得したい値になる 当然といえば当然 特定の次元の列だけのとりかたはよくわからん とれんのかコレ www.kt.rim.or.jp/~kbk/gawk-30/gawk_12.html#SEC119 Using Numbers to Subscript Arrays 配列について重要なのは、配列の添え字は常に 文字列として扱われるということである。 配列の添え字に数字を使った場合、それは添え字付けに使われる前に 文字列に変換される www.kt.rim.or.jp/~kbk/gawk-30/gawk_12.html#SEC121 Multi-dimensional Arrays 多次元配列とは、配列要素の指定を複数の添字の並びによって行う配列である。例え ば二次元の配列は二つの添字を必要とする。 一般的な(awkも含めた大多数の 言語では) 二次元配列の要素に対する参照は grid[x,y]このよ うに行う。 (gridは配列の名前) セパレータには組み込み変数SUBSEPに格納 されている値が使われる。
- 912 名前:デフォルトの名無しさん mailto:sage [2018/12/23(日) 11:43:46.94 ID:7N3pX2Wi.net]
- >>900
それを踏まえて>>888で > gawk4 とわざわざことわっているんじゃないの?
- 913 名前:デフォルトの名無しさん [2018/12/23(日) 22:29:12.74 ID:qffc/3mK.net]
- まず入力から多次元配列を読込む処理でも作ってみるか
できるのかがよく分からん コレがすんなりできないとコレ自体が使えるシロモノにならなそうだしな テストデータは作ってみた https://ideone.com/Sir0IE awkのこの多次元配列についてほかのとこで書いてあるの読んでみると 色々と面倒なことがおきるはのは分かった 特に問題がおきそうなのは一度配列やスカラーで要素を追加すると、 その配列やスカラーを変えて上書きする場合明示的にそれを削除しないと上書きして使えない きっとなノードを削除するときはその要素゙から辿って一番深いとこから再帰的に削除しないと残骸が残る cのメモリリークと同じことが起きると推定される いまいちこの多次元配列に使い道があるのかどうかが分からない
- 914 名前:デフォルトの名無しさん mailto:sage [2018/12/23(日) 23:32:19.00 ID:nM/PpEMV.net]
- lispが最適
awkは不適
- 915 名前:デフォルトの名無しさん [2018/12/24(月) 01:01:19.83 ID:ivcUrO89.net]
- https://ideone.com/PFBwQU
どうにかして動的に配列を構成できないか調べてみたが やりかたが分からん >>894の質問してるのが書いた方法で 一旦多次元配列を読む込むようにはしてみた 質問してるのが欲しいといってる要素の数は 結局入力の行数と同じになる
- 916 名前:デフォルトの名無しさん [2018/12/24(月) 01:07:37.50 ID:ivcUrO89.net]
- https://ideone.com/zTUFL2
switch分のcaseが1つ少なかったから追加しといた
- 917 名前:デフォルトの名無しさん [2018/12/24(月) 09:11:50.63 ID:PbNokzxn.net]
- >>902
> きっとなノードを削除するときはその要素゙から辿って一番深いとこから再帰的に削除しないと残骸が残る delete a は a[1][2] や a[3][4][5] などの子配列含む配列a全体の使用メモリをまとめて "再利用" にまわす 一部の要素を残しておきたい事情が無ければ、delete a[1][2]; delete a[3][4][5]; ... のように子配列を個別に deleteする必要は無い たとえば下の(2)は多次元配列bが多次元配列aの使用済みメモリを再利用するので 終了間際のメモリ使用量は(1)(2)どちらも同じになるが、(2)の delete a を消すと倍程度に増える (1) BEGIN{for(i=1; i<=1000000; i++){a[i%10][i]=i}} (2) BEGIN{for(i=1; i<=1000000; i++){a[i%10][i]=i} delete a; for(i=1; i<=1000000; i++){b[i%10][i]=i}} メモリ再利用の仕組みはThe GAWK Manualには書いていないけどAharon Robbinsが↓で回答している https://groups.google.com/forum/#!topic/comp.lang.awk/CKwoes0_63U
- 918 名前:デフォルトの名無しさん [2018/12/24(月) 15:58:51.02 ID:ivcUrO89.net]
- なるほど
ありがとう きっと再利用されるから 気にせず放置でいいのか
- 919 名前:デフォルトの名無しさん [2018/12/24(月) 17:27:46.25 ID:8PLVwc4u.net]
- >>904 886です。ありがとうございます。動的とはこんな感じでしょうか?
一度作って、削除するという変な仕様ですが。 BEGIN { a[1] = "foo"; a[2][1] = "bar"; a[2][2] = "baz"; a[3] = "qux"; a[4][1][1] = "quux"; a[4][2] = "corge"; for (i = 1; i < 5; i++) { meta_ar_init(b, i); clone(b[i], a); } } function meta_ar_init(ar, init_num) { ar[init_num][1] = ""; delete ar[init_num][1]; } function clone(lhs, rhs, i) { for (i in rhs) { if (isarray(rhs[i])) { lhs[i][1] = ""; delete lhs[i][1]; clone(lhs[i], rhs[i]); } else lhs[i] = rhs[i]; } }
- 920 名前:デフォルトの名無しさん [2018/12/27(木) 20:01:48.39 ID:pQqvXPza.net]
- よく分からんが
例えばそれで>>904の入力データなんかを読み込めたりするのか >>905のswitchだと事前に何次元かわかってないと読み込めない 何次元になるか不明な入力データの場合 どうやれば格納できるかよくわからんんかった
- 921 名前:デフォルトの名無しさん [2018/12/27(木) 22:46:53.38 ID:X7jxTwwp.net]
- >>908の「一度作って、削除する」というのは
https://www.gnu.org/software/gawk/manual/gawk.html#Arrays-of-Arrays ここの一番下のsplitがエラー吐く例の回避策で、配列の要素を最初から配列扱いすることはできないから 予め次階層にダミー要素をぶら下げておき、本命を格納し終えたらダミーは消すって意味かな 自分で書いたらこんなんなったけど、いちおう何次元でも格納できそう https://ideone.com/83ykKF#stdin
- 922 名前:デフォルトの名無しさん [2018/12/30(日) 03:28:21.38 ID:5ft+KBa+B]
- すごいけど配列の値が書いてないので
BEGIN { array_entry(a, "1-2-3", 48) array_entry(a, "1-2-4-6", 667) array_entry(a, "3-1", 0) array_entry(a, "4", 6) array_entry(a, "5-1-2-3-4-5", -128) process_array(a, "a", "do_print", 0) }
function array_entry(a, val, ele , step, b, n) { n = split(val, b, /-/) if (n == 1) { a[val + 0] = ele; return } if (step == n - 2) { a[b[step + 1]][b[n]] = ele; return } a[b[step + 1]]["dummy"]; if (step + 1 < n) { array_entry(a[b[step + 1]], val, ele, step + 1) delete a[b[step + 1]]["dummy"] } }つづく
- 923 名前:デフォルトの名無しさん [2018/12/30(日) 03:29:15.30 ID:5ft+KBa+B]
- function do_print(name, element) {
printf("%s = %s\n", name, element); } function process_array(arr, name, process, do_arrays, i, new_name) { for (i in arr) { new_name = (name "[" i "]"); if (isarray(arr[i])) { if (do_arrays) @process(new_name, arr[i]); process_array(arr[i], new_name, process, do_arrays); } else @process(new_name, arr[i]); } } これでいけそう?
- 924 名前:デフォルトの名無しさん [2018/12/31(月) 02:46:41.48 ID:20SukTdNU]
- ちゃんと書いてみました。
https://ideone.com/rdeTvE
- 925 名前:デフォルトの名無しさん mailto:sage [2019/01/01(火) 00:00:01.96 ID:7rl7mk2H.net]
- 2019年もawkのお世話になります
- 926 名前:デフォルトの名無しさん mailto:sage [2019/01/02(水) 18:12:37.70 ID:0+aicLseW]
- すげー
- 927 名前:デフォルトの名無しさん [2019/01/05(土) 08:05:13.61 ID:1ixBisDID]
- どなたか教えてください
Windows10-32bit,MinGW(msys無し),gawk4.2.1 for win32 bin/src(ezwinports), Shift_JISの環境で builtin.c を書き換えてビルドしました。 書き換えた内容はprintf/sprintfのマルチバイト文字列整形関連です。 ビルド後、期待通りに動きますが、実行ファイルサイズが4.8MBもあります。 上記のソースディレクトリでcmdを起動して mingw32-make mingw32 とタイプしました。 出来上がった gawk.exe のファイルサイズは正常なのでしょうか? また、上記環境ではできませんが configure は必要ですか? よろしくお願いいたします。
- 928 名前:デフォルトの名無しさん mailto:sage [2019/02/05(火) 18:58:36.44 ID:9Z2hbdGL.net]
- 60くらいの教授が40年くらい前にAWKでアセンブラ作ったとか言ってたんだけど
当時に既にあったということと当時から小規模なコンパイラなら作れるくらい高性能だったことに驚いた
- 929 名前:デフォルトの名無しさん mailto:sage [2019/02/05(火) 19:10:49.73 ID:dIIT7BCG.net]
- アセンブラをコンパイラとは呼ばないが
- 930 名前:デフォルトの名無しさん [2019/02/06(水) 10:31:17.59 ID:+qagyc5o.net]
- aho
- 931 名前:デフォルトの名無しさん mailto:sage [2019/02/06(水) 13:09:33.86 ID:j4QdsmCl.net]
- asort、asortiがよくわからなかったので試した結果
# a a[5] ="a5" a[1] ="a1" a[3] ="a8" # asort(a,as) as[1] ="a1" as[2] ="a5" as[3] ="a8" # asorti(a,asi) asi[1]=1 asi[2]=3 asi[3]=5 なんだそういうことだったのかとわかった
- 932 名前:デフォルトの名無しさん mailto:sage [2019/02/06(水) 17:39:23.37 ID:+3VpeZVh.net]
- >>917
思わず "assembler by awk" でググって The Amazing Awk Assembler by Henry Spencer を ダウンロードしちゃったじゃないか。
- 933 名前:デフォルトの名無しさん mailto:sage [2019/02/23(土) 17:41:13.06 ID:Y0E0nwid.net]
- awkでファイルがあるかどうかの判別は、どのようにしたらよいのでしょうか?
具体的にはBEGINの中で getline a < "/dev/stdin"; fn = a".txt" と任意のファイル名を作った後、そのファイルがあるかどうかを確認したいんです。 もしファイルがすでにあったら処理は終了、無ければ以後の処理をそのファイルにリダイレクトする、という感じです。
- 934 名前:デフォルトの名無しさん mailto:sage [2019/02/24(日) 00:16:02.91 ID:Cwr1i6xY.net]
- if(getline<fn!=-1)exit
とか?
- 935 名前:デフォルトの名無しさん mailto:sage [2019/02/24(日) 11:45:53.93 ID:FuDjIOWV.net]
- >>923
できました!ありがとうございます!!
- 936 名前:デフォルトの名無しさん [2019/03/21(木) 08:10:09.34 ID:pGDO/F2C.net]
- 答えが出ないなんで?
#!/usr/bin/awk -f BEGIN{ print game(10, 24); } function game(coin,depth, i,j){ if(memo[coin,depth]){ return memo[coin,depth]; } if(coin == 0){ return 0; } if(depth == 0){ return 1; } win = game(coin + 1, depth - 1); lose = game(coin - 1, depth - 1); memo[coin,depth] = win + lose; }
- 937 名前:デフォルトの名無しさん mailto:sage [2019/03/21(木) 09:51:18.96 ID:WMaCNtBE.net]
- 最後の memo[coin,depth] = win + lose はそのまま関数の戻り値として
return しなければならないが、それを忘れている。 さらに、正しい答えが返らない原因が 2 点。 関数定義の引数名間違い: i,j → win,lose。 if(depth == 0) と if(coin == 0) の判定を行う順序が逆。
- 938 名前:デフォルトの名無しさん [2019/03/21(木) 14:19:16.55 ID:pGDO/F2C.net]
- >>926
ありがとうございます。 そっか。returnがいるんですね。 perlだと最後はreturn省略可能だけどawkは省略不可みたい。 あと、引数名も間違っていました。 正しい答え出ました!
- 939 名前:デフォルトの名無しさん mailto:sage [2019/03/21(木) 21:25:33.68 ID:ZeSQsBE1.net]
- それぐらいの処理は、Ruby で作れ!
- 940 名前:デフォルトの名無しさん mailto:sage [2019/03/21(木) 23:54:47.78 ID:7AyLRSvD.net]
- オーク英雄物語 〜忖度列伝〜
https://ncode.syosetu.com/n8418ff/1/ 👀 Rock54: Caution(BBR-MD5:0be20a4887bc3d3353f527d3636c44e3)
- 941 名前:デフォルトの名無しさん mailto:sage [2019/04/01(月) 17:01:28.78 ID:nwflCE8J.net]
- >>928
awkの方がいいときもある installしなくていい タスクマネージャでみているとrubyよりメモリを食わない時もある 融通の利く配列が超便利 通信、Hash、sortなど使いまくる時はrubyのほうがいいけど
|

|