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/
809 名前:795 [2016/09/14(水) 23:40:38.22 ID:YCeX8Gov.net] やってみたよ。環境は Debian jessie。 テストプログラム #!/usr/bin/perl -w use strict; { my $do_ps = 'system("ps p $PPID o pid,sz,args")'; foreach ( 1,'sprintf("1")'){ system('gawk',"BEGIN { for(i=1;i<=1000000;i++){a[i]=$_} $do_ps;}"); } } 実行結果 PID SZ COMMAND 7389 7693 gawk BEGIN { for(i=1;i<=1000000;i++){a[i]=1} system("ps p $PPID o pid,sz,args");} PID SZ COMMAND 7392 158116 gawk BEGIN { for(i=1;i<=1000000;i++){a[i]=sprintf("1")} system("ps p $PPID o pid,sz,args");} KB 単位らしいから 8MB と 160MB 。ただごとじゃない差だね。 1 を "1" に変更してもこんな感じだから数値と文字列の差というわけではなさそう。
810 名前:デフォルトの名無しさん [2016/09/14(水) 23:49:14.48 ID:YCeX8Gov.net] ごめん、書き忘れた。 GNU Awk 4.1.1, API: 1.1 (GNU MPFR 3.1.2-p3, GNU MP 6.0.0) Copyright (C) 1989, 1991-2014 Free Software Foundation.
811 名前:デフォルトの名無しさん [2016/09/17(土) 08:30:37.61 ID:didBD5ba.net] よく考えたら、メモリの使用量自体じゃなくて、それがどれだけ増えたかが重要だね。 そして、連想配列の構造体とキーに必要な量はどのケースでも同じと考えられる。 つまり、連想配列の要素のための量がどれだけ違うかを直接知ることができるはず。 というわけで、もう一回テスト。 https://ideone.com/mRuFj7
812 名前:デフォルトの名無しさん [2016/09/17(土) 08:32:42.20 ID:didBD5ba.net] 実行結果 element before after diff 1 5685 7691 2006 i 5685 29226 23541 sprintf("%d",i) 5685 158124 152439 sprintf("%d",i) + 0 5685 29221 23536 sprintf("%d",i) "" 5685 37026 31341 1000000 要素の配列で 2MB って、いったいどうやってるんだろう。少なすぎる。 sprintf("%d",i) が突出して多いのは sprintf で多めに確保して 切り詰めたりせずにそのまま使ってるのだろうか。 さあ、gawk のソースコードをハックしてみるか!
813 名前:デフォルトの名無しさん mailto:sage [2016/09/17(土) 14:11:27.89 ID:IIH0ZjSk.net] 推測だけど、stream, yield, callback、遅延処理かも データをバッファサイズ分だけ読み込んで処理して、 次のコマンドへ送ったら、それを捨てて、次のデータを読み込むのかも この方式だとメモリは、バッファサイズ分だけしか使わない
814 名前:デフォルトの名無しさん [2016/09/18(日) 10:41:36.96 ID:6jI6cHER.net] ベクターに公開されてるgawk3.1.5(と非公開の3.1.7)、ヘンテコな処理が見つかったのでメモ このgawkのsystem関数を実行すると、環境変数TMPが指してるフォルダに @echo off system関数の引数 という2行が書かれたバッチファイルpip?.bat(?はsystem実行回数+1)というのが作成され
815 名前:デフォルトの名無しさん [2016/09/18(日) 10:44:42.56 ID:6jI6cHER.net] ・・・いっぺんに書こうとしたらハネられるorz
816 名前:803 [2016/09/18(日) 10:46:32.08 ID:6jI6cHER.net] (続き) それを/c pip?.batで起動、完了後にpip?.batを 削除という流れでコマンドが実行される
817 名前:803 [2016/09/18(日) 10:47:07.98 ID:6jI6cHER.net] (続き) system関数を使ったスクリプトを同時に1つしか実行しないなら良いけど 2つ以上実行したときはタイミング次第でpip?.batの数字がぶつかり、先に実行した側が ・ コマンドが実行されない ・ コマンドが実行されるけど、完了後に「バッチファイルが見つかりません」が吐かれる という結果になる 予めcmdの窓ごとにTMPを変えておけば問題ないけど面倒くさい コマンド | getlineで起動したほうが手っ取り早いと思う (ただし出力が2KBytes溜まると止まるから適宜リダイレクトする) でも何でこんな方法でsystem関数を実装したんだろうね(´・ω・`)
818 名前:デフォルトの名無しさん mailto:sage [2016/09/18(日) 13:53:41.51 ID:EIh/dcA1.net] tmpfile を使えば、他と重複しない、ランダムな名前のファイルを作れるのに、 どうして使わないのだろう?
819 名前:デフォルトの名無しさん [2016/09/18(日) 14:54:02.97 ID:KtcAr9oX.net] MS-DOS ではね、コマンドラインの長さの制限が厳しかったんだよ。驚くなかれ、たった 128 バイトだ。 そんな環境では、バッチファイルにすれば実行できるけど command /c "prog arg1 arg2 ..." では command /c のせいで制限を越えるということもあるだろう。つまり、そういうことだ。 ………冗談だ。確かにそういう制限はあったけど。 現在はもう system 関数ではそういうことをしていないということが ChangeLog に書かれてるよ。 2014-01-15 Eli Zaretskii <eliz@gnu.org> * popen.c (os_system): Use spawnl, and quote the command line, to be consistent with what gawk_popen does. (os_popen) [__MINGW32__]: Don't scriptify the command, to be consistent with gawk_popen. (os_pclose) [__MINGW32__]: Update to match os_open: no need to unlink the script file.
820 名前:デフォルトの名無しさん [2016/09/18(日) 15:07:54.47 ID:KtcAr9oX.net] でもソースコードを見るかぎり、パイプではそういうことをしてるみたいなんだけど…… ちょっと試してみてくれないかな。 system("dir") | getline みたいな感じ? よく知らないけど。
821 名前:803 [2016/09/18(日) 16:19:12.82 ID:6jI6cHER.net] コマンド | getline で起動する場合はpip?.batは作られませんでした system関数だけpip?.bat経由の模様 klabaster版のwindows用gawk4.1.3だとsystem関数がpip?.batを 作らなかったから、ベクター版固有の動きかなあと思います
822 名前:デフォルトの名無しさん [2016/09/18(日) 17:46:00.36 ID:KtcAr9oX.net] ありがとうございます。 gawk-4.1.1 の pc/popen.c を見た限りでは gawk の system 関数でバッチファイルを作るのは MINGW 限定で、 ChangeLog には問題が解消されたから直接 spawnl で実行するようにしたと書かれているわけですが gawk のパイプ処理を実行している(と思われる) os_popen 関数ではバッチファイルを作るときと同様に tempnam 関数でファイル名を作った上で、そのファイルを経由して受け渡しをしているように見えます。 これは MS-DOS の時代から使われてるやり方で、パイプのように見えてもパイプではありません。 このやり方だと gawk で while (( command | getline) > 0) と書いても実質的には system("command > filename"); while (( getline < "filename") > 0) と同じことになります。 あくまでも 4.1.1 の pc/popen.c の os_popen 関数がそう見えるというだけで、実際には違うかもしれませんが 自分で試すことができません。そもそも 3.1.5 のソースコードってどこにあるの? もし勘違いじゃないなら >>807 と同じ問題が起こりそうな気が…… Linux を使ってる自分には関係ないといってしまえばそれまでですが。
823 名前:デフォルトの名無しさん mailto:sage [2016/09/18(日) 19:56:17.75 ID:zTPoEkjL.net] >>812 vectorの配布ファイル内のreadmeにはソースコードの 公開場所を探してるとか、直接連絡すれば渡すとか書いてある。 Windows版、NTあたりから一時ファイル作らずにパイプ動作するように なったとか、どこかで読んだ気がするけど。
824 名前:デフォルトの名無しさん [2016/09/18(日) 22:03:20.37 ID:KtcAr9oX.net] 謎は解けた。 ファイルを使ってデータを渡すのはマクロ __DJGPP__ とマクロ __MINGW32__ が いずれも定義されていない場合らしいです。 Vector のは MINGW なので該当しません。お騒がせしました。
825 名前:デフォルトの名無しさん mailto:sage [2016/09/19(月) 11:56:06.00 ID:iIvzjj/t.net] ファイルを経由していても、ストレージに書き込むとは限らない メモリ上だけに存在する、ファイルもあり得る。 LinuxのRAMディスク、tmpfs とか
826 名前:803 [2016/09/19(月) 14:26:19.66 ID:fDWhtT6v.net] >>812 情報ありがとうございます。>>804 で書いた「ヘンテコな処理」をpc\popen.c内に確認できました。 scriptify関数のtempnam呼んでるところでプロセスIDもつけるなり、細工したいなあ・・・
827 名前:デフォルトの名無しさん [2016/09/20(火) 17:00:26.41 ID:RIxgZ1yj.net] 先日アクセスできなかった GNU のサイトが復活してたので 3.1.5 のソースコードを入手できました。 やっぱり os_popen からも scriptify を呼んでたみたいですね。4.1.1 のソースコードじゃ判りませんでした。 一応 chdir はアトミックな処理のはずなのでリスク回避に役立つと思いますよ。それ以外に方法がなければ。 chdir したら rmdir も忘れずに。
828 名前:デフォルトの名無しさん [2016/09/20(火) 17:06:03.57 ID:RIxgZ1yj.net] 間違えた。chdir じゃなくて mkdir です。
829 名前:デフォルトの名無しさん [2016/09/22(木) 12:11:24.09 ID:nnsRF/zz.net] >>795 どうやら >>802 で想像した通り sprintf の仕様らしい。 本体は builtin.c の format_tree 関数らしい。 最初に 512 バイト確保したバッファは大きくはなっても小さくはならない。 実際の文字列に合わせて確保しなおしたらどうなるか >>801 のテストをしてみたよ。 改造前 element before after diff 1 2753 4757 2004 i 2753 22357 19604 sprintf("%d",i) 2753 151283 148530 sprintf("%d",i) + 0 2753 22376 19623 sprintf("%d",i) "" 2753 30174 27421 改造後 element before after diff 1 2753 4757 2004 i 2753 22357 19604 sprintf("%d",i) 2753 30174 27421 sprintf("%d",i) + 0 2753 22373 19620 sprintf("%d",i) "" 2753 30230 27477 あれ? jessie の gawk と比べてメモリの使用量が少ない。 -DDEBUG 付きでコンパイルしたから増えるかと思ったのに。 まあ、それ以外は一応予想通りではある。
830 名前:デフォルトの名無しさん [2016/09/22(木) 23:15:31.17 ID:SYBS8P/o.net] >>794 とか 文字列の連結は "A" "B" よりもsprintf("%s%s", "A", "B") の方が速いとか gawkって結構クセありますね
831 名前:デフォルトの名無しさん mailto:sage [2016/09/23(金) 02:39:22.63 ID:o4qLonoN.net] >>820 > 文字列の連結は "A" "B" よりもsprintf("%s%s", "A", "B") の方が速い マジか。逆だと聞いていたが。
832 名前:デフォルトの名無しさん [2016/09/23(金) 16:06:39.19 ID:Y+5MXC/e.net] そんなバカな……と思ってやってみた。 https://ideone.com/jIYn2p jessie 用のパッケージによる実行結果。 i++ 6.15614 i = i + 1 6.02501 cat " and " dog 13.0163 sprintf 19.1612 インクリメントと足し算の差は有意とは思えない。 連結と sprintf の差は多分、倍くらい。 sprintf の中の複雑さを考えれば意外と差は小さいといえる。 フォーマット文字列が定数なら正規表現みたいにコンパイルすれば 高速化できる……のかなあ? 自分でやってみようとは(今はまだ)思わない。
833 名前:デフォルトの名無しさん [2016/09/24(土) 23:15:47.76 ID:+IiHRmp0.net] Windowsで使えるawkでUnicodeを正しく処理できる(length("あいう")で3が返ってくる)ものは Cygwin版とVector版以外に無いでしょうか?
834 名前:デフォルトの名無しさん [2016/09/25(日) 10:08:34.07 ID:BH82R274.net] 何があったんですか? tanimoto.to/nlp/jgawk/jgawk.html に書かれているようなことですか? 別の選択肢も一応あるみたいですが。 トランスレータでもいいなら Perl に a2p が同梱されてます。
835 名前:822 [2016/09/25(日) 14:28:36.60 ID:MNlfsMjx.net] 特に困りごとは無いのですが、最新のVer4.1.4やその近辺のバージョンで Unicodeが正しく処理できるものがあれば、今使っているBruce版3.1.7から 乗り換えたいなあと思いまして。 ↓の5年前に書かれた記事の頃より選択肢が増えたりしてたら嬉しいなと・・・。 blog.livedoor.jp/corbie/archives/3924154.html
836 名前:823 [2016/09/26(月) 09:17:05.22 ID:bhAuZr+w.net] 理解しました。全滅だったんですね。 Windows での事情は存じませんが、こちらでも取り急ぎ gawk 3.1.5 を make してみました。 ところで、そのページのテスト3は不十分です。 UTF-8 でのパターンマッチは通常文字の誤マッチは原理的に起こりません。起こったらバグです。 だから、UTF-8 に対応しているかどうかをテストするために sub(/.う/, "U") というようなものを入れて試してみました。 今ビルドしたばかりの gawk 3.1.5 と jessie のパッケージの gawk 4.1.1 がこのテストに合格しました。 mawk 1.3.3 もインストールされてましたが、こちらはマルチバイト文字に対応していないようです。 さて、結論です。 シフトJIS に対応しているとされるものは避けた方がいいと思います。 余計な改造はしない方が信頼性は高いでしょう。 length がバイト数なのは、単にマルチバイト文字非対応でコンパイルされてるからだと思います。 マルチバイト文字対応版を誰かがリリースしてくれるのを待つか、自分でコンパイルするかですね。
837 名前:デフォルトの名無しさん [2016/09/27(火) 17:33:47.16 ID:Icjzq3KF.net] Linux では環境変数 LANG に UTF-8 が入ってないと期待通りに動いてくれません。 正確には LANG というより LC_CTYPE ですが、それはおいといて。 もしかしたらと思って、自分には無用だと思ってた Wine で klabaster gawk 4.1.3 を動かしてみました。 ところが、正規表現にマルチバイト文字が現れた時点で怒られます。 どうやら LANG が無いか、LANG=C じゃなければマルチバイト文字を使えないようです。 そして結局、正規表現の . や length を UTF-8 モードにする方法は見つけられませんでした。 記事のコメントには LC_ALL=ja_JP.UTF-8 で動くって書いてあるのに。 ひょっとして、Windows では原理的にできないということ? これはいよいよ a2p が現実的な選択肢か? ……と思ったら、出力する Perl コードが間違ってます。 もう降参です。UTF-8 対応の gawk をお望みの方には Linux への引越しを強くお奨めします。
838 名前:デフォルトの名無しさん mailto:sage [2016/09/27(火) 18:24:36.25 ID:JiNhKH2a.net] cygwinやmsys2のgawkを使うのはだめなの?
839 名前:デフォルトの名無しさん mailto:sage [2016/09/27(火) 18:34:39.64 ID:BPXrtVfk.net] Windows Subsystem for Linux (WSL)では、Ubuntu64の実行ファイルが動く。 Linux API を、Windows API へ変換して呼び出す Ubuntuのパッケージも、apt-getでインストールできる
840 名前:デフォルトの名無しさん [2016/09/27(火) 19:26:43.05 ID:Icjzq3KF.net] だめというか、見つけられなかった。 ただでさえ Windows のことなんか知らないんだからこれ以上無理。 いい方法を知ってたら教えてあげて。
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です。 親ノード毎?に保存する方法がまだわかりませんが、 明日以降考えます。 みなさん、ご協力ありがとうございました。