awkについて語るスレ $2
■ このスレッドは過去ログ倉庫に格納されています
腐っても鯛? 騏も老いては駑馬に劣る? 三人の碩学が生み出したスクリプト言語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/ >>749 $ は演算子だから、a=b+1をa = b + 1と書くようなものかな。 式が書けるね。 $ は一番優先順位が高いから、かっこで括らにゃいかんが。 今はじめて知った。haskellの$は演算子だって知ってたけど、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分程度だった。 Gawk4.1.2が出たなあ、と思ってたらすぐ4.1.3が出た。 素人には違いがあまり分からんのだが。 http://www.amazon.co.jp/AWK 実践入門-Software-Design-plus-中島/dp/477417369X 新しい本、出たんだな 廃れないのが凄い >>765 買ってきた。まだ最初の方と最後の方を眺めただけだけど。 ページiv(「はじめに」)でawkの表記について「本書内では、いずれの 場合もすべて小文字のawkという表現に統一しております」と あるのに、書名がAWK。 巻末のリファレンスで気になったところ。 演算子の優先順位に触れていない、フィールド演算子が 「特別な意味を持つな変数」の中に入れられている。 参考書や文献がないけど、今時は「ネットでググれ」かな。 Mono: Playback -9707 [5%] [-97.07dB] [on] 上の行からパーセントを除いた数字(上の例だと5)を取得したいのですがどのようにしたらよいでしょうか? パーセントの値は0から100の整数だと思います # $0 に入っているとして sub(/%.*/, ""); sub(/.*[^0-9]/, ""); awk -F"[%[]" '{print $2}' ではまずい? >>768 ,769 ありがとうございました どちらでも希望の結果を求めることができました テンプレである筈の1が読めないんだが、このスレ的にはPOSIXで書くのが 正統?普段はGawkしか使わないので一応確認。 awk の a は、aho の a ただし、エイホと読むらしい へぇーーーーー awk使ってるシェルスクリプト見ると逃げてるなあと思う 普通は x[3]=5 と書くが、=なしの x[3] だけでもエラーとならず、x を配列として確保し、length(x)=1 になるのを発見 まあ、あまり必要ないけど まあ、gawkのマニュアルでも代入の前に参照が出てくるし IGNORECASE=1 をBEGIN の前に置いてもエラーにならず、不可解動作 セキュリティ的にやばくないの >>778 BEGIN セクションを先頭に書けとは何処にも書いてない。 BEGIN を最後に書いても END を最初に書いても問題は無い。 何処に書いても、実際には先頭行読み込み前、各行読み込み時、最終行読み込み後にそれぞれ パターンマッチが行われている。 ただマッチする条件が特殊だから、先頭か最後でしか中の文が実行されないだけ。 サッカーブッシュ日本代表日程ぷあたん(しゅっちょうまいくろ教育長交代)春文執行40代売上差額シュガーチョコ https://www.youtube.com/watch?v=NDq1QoJY0nY 宇ドナルドアナリストパワーストーンコーチングとしまえん サッカーブッシュ日本代表日程古本屋よしたけしゅっちょうちょこしゅがー ディーラー税務署天才開発者死亡詰みヨミドクターマイクロサービス不足 サッカーブッシュ日本代表日程ぷあたんシフト光金さかい強制バイト人権侵害問題 春分資源執行ニューヨーク低原価ぼったステーキソルトレイク福岡横浜新橋奴隷課金パチシフト強制バイト問題新潟米センター生残 コスメ24チャリティー隠れ40代生活保護プレイボーイバイトレードいたりあん接待問題 マスコミKARDローンケーオーサービス不足婚活パーティー寄付金執行原発ビジネス FBIチャイニーズタイホテル売上事務所ガチャ決算ガチャキャンペーン(販売報道陣過激派組織向携帯最新情報提供終了 校長発言細心注意ノートン産廃エラー(著作権クレーム中国反応融資高額教育費)(中国捕鯨団体40代社員サッカーコメント 高額入学金ヤフウ新橋大学ヤフウ新橋理事長FX経費 おじや50代資産ガリバズフィード40代エリート mawk32.exeで「multibyte char」のメッセージがでて困ってます、何が原因でしょう? 抑止する方法はありますか? multibyte指定のコマンドラインオプションは無いようなのですが? UTF-8 が使えないのかも 「mawk multibyte char」で検索! >782 データもプログラムもSJISです。 何に反応して multibyte charが出続けるのか不明です。 gawk高速なので満足なのですが、STDERRに multibyte charがで続けるのでうざいし、この出力ぶんだけ速度も低下? 入力にSJISでない文字が混在していることない? nkf -s 入力ファイル | awk で変換したら コードを教えて下さい。 チャレンジしましたが、これではダメです。。 (for i=1, i<=NF, i++){ if $i<0{$i=0} } print $0 したいことは、下記のような行列の数字があって、負の値をゼロに置換したいです。 ▼元の行列 3 15 6 1 -5 4 0 2 8 9 -7 11 ▼やりたい変換後の行列イメージ 3 15 6 1 0 4 0 2 8 9 0 11 構文がぜんぜん駄目。 {for(i=1;i<=NF;i++)if($i<0){$i=0};print $0;} 「したいことは、〜したいです。」の構文も駄目。典型的なねじれ文。 >>787 Ruby, Python スクリプトを提示してみろよ。 >>786 ありがとうございます!出来ました! (一行プログラミング!awk便利ですね) awk じゃなくてもいいんなら $ sed 's/-[0-9][0-9]*/0/g' ... GNU sed なら $ sed -r 's/-[0-9]+/0/g' ... でええんちゃう? かまぷ 「『シェル芸』に効く AWK処方箋」 エイホ先生「AWKって使い捨ての言語(中略)プラスアルファの処理がやりたいよね。 ただその処理はとても簡単な処理でいい。そこに対して新しいプログラム言語を作っていきたい」 AWKブーム第1世代は「アイドル辞書」で学んだ――日本GNU AWKユーザー会 斉藤さん (1/5):CodeZine(コードジン) http://codezine.jp/article/detail/9478 2016/06/15 14:00 やたらと続きは登録して読めと言われてもなあ。 このスレが立った頃からJGAUCのHPが更新されていないってのも凄い。 Windows版のgawkで遊んでたら for (i=0; i<n; i++) より for (i=0; i<n; i+=1) のほうが 実行時間が短くなることに気づいた なんだこりゃ for(i=1;i<=1000000;i++){a[i]=1} と for(i=1;i<=1000000;i++){a[i]=sprintf("1")} 結果は同じはずなのに、後者は異常にメモリを食う!ふしぎ! 同じじゃないぞ。数値と文字列だ。 ところで、君が使ってる awk はどれ? apropos awk ってやってみたら、こんなん出てきた。 gawk (1) - パターン検索・処理言語 igawk (1) - インクルードファイルを使う gawk a2p (1) - Awk to Perl translator awk (1) - pattern scanning and text processing language English (3perl) - use nice English (or awk) names for ugly punctuation v... mawk (1) - pattern scanning and text processing language nawk (1) - pattern scanning and text processing language >>795 例が悪くてスマソ、Cygwin上でgawk4.1.4使って for(i=1;i<=1000000;i++){a[i]="1"} と for(i=1;i<=1000000;i++){a[i]=sprintf("1")} でループ脱出直後のメモリ使用量を比較すると 上が60MBytes、下が600MBytesとかになった cmdで動くgawkの3.1.7でも同じような差がでた Linuxは試していないけど、もし大丈夫ならWindows版の問題かも >>796 OSX El Capitan gawk 4.1.4 それぞれBEGIN{}に入れたスクリプトを読み込ませて実行。 で前者数十MB、後者3GB超までメモリ使った(アクティビティモニタ)。 やってみたよ。環境は 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" に変更してもこんな感じだから数値と文字列の差というわけではなさそう。 ごめん、書き忘れた。 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. よく考えたら、メモリの使用量自体じゃなくて、それがどれだけ増えたかが重要だね。 そして、連想配列の構造体とキーに必要な量はどのケースでも同じと考えられる。 つまり、連想配列の要素のための量がどれだけ違うかを直接知ることができるはず。 というわけで、もう一回テスト。 https://ideone.com/mRuFj7 実行結果 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 のソースコードをハックしてみるか! 推測だけど、stream, yield, callback、遅延処理かも データをバッファサイズ分だけ読み込んで処理して、 次のコマンドへ送ったら、それを捨てて、次のデータを読み込むのかも この方式だとメモリは、バッファサイズ分だけしか使わない ベクターに公開されてるgawk3.1.5(と非公開の3.1.7)、ヘンテコな処理が見つかったのでメモ このgawkのsystem関数を実行すると、環境変数TMPが指してるフォルダに @echo off system関数の引数 という2行が書かれたバッチファイルpip?.bat(?はsystem実行回数+1)というのが作成され (続き) それを/c pip?.batで起動、完了後にpip?.batを 削除という流れでコマンドが実行される (続き) system関数を使ったスクリプトを同時に1つしか実行しないなら良いけど 2つ以上実行したときはタイミング次第でpip?.batの数字がぶつかり、先に実行した側が ・ コマンドが実行されない ・ コマンドが実行されるけど、完了後に「バッチファイルが見つかりません」が吐かれる という結果になる 予めcmdの窓ごとにTMPを変えておけば問題ないけど面倒くさい コマンド | getlineで起動したほうが手っ取り早いと思う (ただし出力が2KBytes溜まると止まるから適宜リダイレクトする) でも何でこんな方法でsystem関数を実装したんだろうね(´・ω・`) tmpfile を使えば、他と重複しない、ランダムな名前のファイルを作れるのに、 どうして使わないのだろう? 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. でもソースコードを見るかぎり、パイプではそういうことをしてるみたいなんだけど…… ちょっと試してみてくれないかな。 system("dir") | getline みたいな感じ? よく知らないけど。 コマンド | getline で起動する場合はpip?.batは作られませんでした system関数だけpip?.bat経由の模様 klabaster版のwindows用gawk4.1.3だとsystem関数がpip?.batを 作らなかったから、ベクター版固有の動きかなあと思います ありがとうございます。 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 のソースコードってどこにあるの? もし勘違いじゃないなら >>806 と同じ問題が起こりそうな気が…… Linux を使ってる自分には関係ないといってしまえばそれまでですが。 >>811 vectorの配布ファイル内のreadmeにはソースコードの 公開場所を探してるとか、直接連絡すれば渡すとか書いてある。 Windows版、NTあたりから一時ファイル作らずにパイプ動作するように なったとか、どこかで読んだ気がするけど。 謎は解けた。 ファイルを使ってデータを渡すのはマクロ __DJGPP__ とマクロ __MINGW32__ が いずれも定義されていない場合らしいです。 Vector のは MINGW なので該当しません。お騒がせしました。 ファイルを経由していても、ストレージに書き込むとは限らない メモリ上だけに存在する、ファイルもあり得る。 LinuxのRAMディスク、tmpfs とか >>811 情報ありがとうございます。>>803 で書いた「ヘンテコな処理」をpc\popen.c内に確認できました。 scriptify関数のtempnam呼んでるところでプロセスIDもつけるなり、細工したいなあ・・・ 先日アクセスできなかった GNU のサイトが復活してたので 3.1.5 のソースコードを入手できました。 やっぱり os_popen からも scriptify を呼んでたみたいですね。4.1.1 のソースコードじゃ判りませんでした。 一応 chdir はアトミックな処理のはずなのでリスク回避に役立つと思いますよ。それ以外に方法がなければ。 chdir したら rmdir も忘れずに。 間違えた。chdir じゃなくて mkdir です。 >>794 どうやら >>801 で想像した通り sprintf の仕様らしい。 本体は builtin.c の format_tree 関数らしい。 最初に 512 バイト確保したバッファは大きくはなっても小さくはならない。 実際の文字列に合わせて確保しなおしたらどうなるか >>800 のテストをしてみたよ。 改造前 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 付きでコンパイルしたから増えるかと思ったのに。 まあ、それ以外は一応予想通りではある。 >>793 とか 文字列の連結は "A" "B" よりもsprintf("%s%s", "A", "B") の方が速いとか gawkって結構クセありますね >>819 > 文字列の連結は "A" "B" よりもsprintf("%s%s", "A", "B") の方が速い マジか。逆だと聞いていたが。 そんなバカな……と思ってやってみた。 https://ideone.com/jIYn2p jessie 用のパッケージによる実行結果。 i++ 6.15614 i = i + 1 6.02501 cat " and " dog 13.0163 sprintf 19.1612 インクリメントと足し算の差は有意とは思えない。 連結と sprintf の差は多分、倍くらい。 sprintf の中の複雑さを考えれば意外と差は小さいといえる。 フォーマット文字列が定数なら正規表現みたいにコンパイルすれば 高速化できる……のかなあ? 自分でやってみようとは(今はまだ)思わない。 Windowsで使えるawkでUnicodeを正しく処理できる(length("あいう")で3が返ってくる)ものは Cygwin版とVector版以外に無いでしょうか? 何があったんですか? http://tanimoto.to/nlp/jgawk/jgawk.html に書かれているようなことですか? 別の選択肢も一応あるみたいですが。 トランスレータでもいいなら Perl に a2p が同梱されてます。 特に困りごとは無いのですが、最新のVer4.1.4やその近辺のバージョンで Unicodeが正しく処理できるものがあれば、今使っているBruce版3.1.7から 乗り換えたいなあと思いまして。 ↓の5年前に書かれた記事の頃より選択肢が増えたりしてたら嬉しいなと・・・。 http://blog.livedoor.jp/corbie/archives/3924154.html 理解しました。全滅だったんですね。 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 がバイト数なのは、単にマルチバイト文字非対応でコンパイルされてるからだと思います。 マルチバイト文字対応版を誰かがリリースしてくれるのを待つか、自分でコンパイルするかですね。 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 への引越しを強くお奨めします。 cygwinやmsys2のgawkを使うのはだめなの? Windows Subsystem for Linux (WSL)では、Ubuntu64の実行ファイルが動く。 Linux API を、Windows API へ変換して呼び出す Ubuntuのパッケージも、apt-getでインストールできる だめというか、見つけられなかった。 ただでさえ Windows のことなんか知らないんだからこれ以上無理。 いい方法を知ってたら教えてあげて。 Cygwin は試してみたけどインストーラに丁重にお断りされたよ。 たくさんの情報ありがとうございます。現状でWindowsに拘るなら、Bruce版3.1.7を継続して 使用するか、Cygwin版に乗り換えるか、Windows Subsystem for Linuxで動作させるかの いずれかになりそうですね。 CygwinやWindows7でのWindows Subsystem for Linuxは、どちらも別途インストールが必要 とのことなので、職場の自PCはともかくスクリプト配布先に(スクリプトを動かすためだけに) 導入してもらわないといけないのはちょっと難しそうです。 Cygwinの導入状況とWindows10への切り替え時期の様子を見つつ、しばらくBruce版3.1.7を 使うことにします。 実は方法が無いわけではない。シングルバイトモードならできる。でも本当にやりたい? 本当に真剣に必要としているなら、このスクリプトでテスト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; } やっぱり 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 の時だけエラーになるのだろう。 >>749 からのレスで、$が演算子だったの? というようなところが気になって 少し調べてみた(調べたというほどの作業はしてないか)。 まず書籍。手持ちの数冊で確認。 『プログラミング言語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実践入門』(技術評論社 初版) >>766 にあるように特別な変数として扱われており、リファレンスにも$が演算子で あることの記載がない。 (続く) (続き) ネットの情報。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という変数にフィールドが代入されると説明しているところもあった。そのように理解して スクリプトを書いてもさして不都合はないだろうな、とは思うが。 広範な調査乙。Gawkのrefcardでもちゃんとoperatorに含まれているなあ。 演算子と明確に認識していなくても、$の後に式OKと思っていれば差し支えなさそう。 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・・・残念 } >>756 こういう過疎スレで無駄に突っかかってくるやつむかつくんだが死ね awkスクリプトをCソースに変換してコンパイルするための「awka」というツールでできるだけ簡単にUTF−8サポートさせる方法を知りたいです。 ネットで散々調べましたがないようです? >>843 それがあなたの現在の実力だったということです お疲れ様でした gawkに対応してるなら大丈夫ってことかな? asciiしか考えていないなら、ソース全チェック…。 要するに、日本語化するんだろうけど。 全然別の言語変換にちょっと咬んだことがあるんだけど、 製品化しちゃってからダブルバイト考慮してないことがわかって、かなり面倒だった。 とりあえず変換してから、ソース見て直すほうが早かったり(笑 がんばってね。 awkで $1,$2...$6 こんな出力を↓下にしたいんだけど どうすればいいですかね? 470230 470290 ↓ 002347 002479 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 }' ありがとう gawk いれないでなんとかならないかな ■ このスレッドは過去ログ倉庫に格納されています
read.cgi ver 07.5.4 2024/05/19 Walang Kapalit ★ | Donguri System Team 5ちゃんねる