awkについて語るスレ $2

1デフォルトの名無しさん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/

821デフォルトの名無しさん2016/09/23(金) 16:06:39.19ID:Y+5MXC/e
そんなバカな……と思ってやってみた。

https://ideone.com/jIYn2p

jessie 用のパッケージによる実行結果。

i++         6.15614
i = i + 1      6.02501
cat " and " dog   13.0163
sprintf       19.1612

インクリメントと足し算の差は有意とは思えない。
連結と sprintf の差は多分、倍くらい。
sprintf の中の複雑さを考えれば意外と差は小さいといえる。
フォーマット文字列が定数なら正規表現みたいにコンパイルすれば
高速化できる……のかなあ? 自分でやってみようとは(今はまだ)思わない。

822デフォルトの名無しさん2016/09/24(土) 23:15:47.76ID:+IiHRmp0
Windowsで使えるawkでUnicodeを正しく処理できる(length("あいう")で3が返ってくる)ものは
Cygwin版とVector版以外に無いでしょうか?

823デフォルトの名無しさん2016/09/25(日) 10:08:34.07ID:BH82R274
何があったんですか?

http://tanimoto.to/nlp/jgawk/jgawk.html

に書かれているようなことですか? 別の選択肢も一応あるみたいですが。
トランスレータでもいいなら Perl に a2p が同梱されてます。

8248222016/09/25(日) 14:28:36.60ID:MNlfsMjx
特に困りごとは無いのですが、最新のVer4.1.4やその近辺のバージョンで
Unicodeが正しく処理できるものがあれば、今使っているBruce版3.1.7から
乗り換えたいなあと思いまして。

↓の5年前に書かれた記事の頃より選択肢が増えたりしてたら嬉しいなと・・・。
http://blog.livedoor.jp/corbie/archives/3924154.html

8258232016/09/26(月) 09:17:05.22ID:bhAuZr+w
理解しました。全滅だったんですね。
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 がバイト数なのは、単にマルチバイト文字非対応でコンパイルされてるからだと思います。
マルチバイト文字対応版を誰かがリリースしてくれるのを待つか、自分でコンパイルするかですね。

826デフォルトの名無しさん2016/09/27(火) 17:33:47.16ID:Icjzq3KF
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 への引越しを強くお奨めします。

827デフォルトの名無しさん2016/09/27(火) 18:24:36.25ID:JiNhKH2a
cygwinやmsys2のgawkを使うのはだめなの?

828デフォルトの名無しさん2016/09/27(火) 18:34:39.64ID:BPXrtVfk
Windows Subsystem for Linux (WSL)では、Ubuntu64の実行ファイルが動く。
Linux API を、Windows API へ変換して呼び出す

Ubuntuのパッケージも、apt-getでインストールできる

829デフォルトの名無しさん2016/09/27(火) 19:26:43.05ID:Icjzq3KF
だめというか、見つけられなかった。
ただでさえ Windows のことなんか知らないんだからこれ以上無理。
いい方法を知ってたら教えてあげて。

830デフォルトの名無しさん2016/09/27(火) 19:51:11.26ID:Icjzq3KF
Cygwin は試してみたけどインストーラに丁重にお断りされたよ。

8318222016/09/27(火) 23:10:22.59ID:eGFFwbsN
たくさんの情報ありがとうございます。現状でWindowsに拘るなら、Bruce版3.1.7を継続して
使用するか、Cygwin版に乗り換えるか、Windows Subsystem for Linuxで動作させるかの
いずれかになりそうですね。

CygwinやWindows7でのWindows Subsystem for Linuxは、どちらも別途インストールが必要
とのことなので、職場の自PCはともかくスクリプト配布先に(スクリプトを動かすためだけに)
導入してもらわないといけないのはちょっと難しそうです。
Cygwinの導入状況とWindows10への切り替え時期の様子を見つつ、しばらくBruce版3.1.7を
使うことにします。

832デフォルトの名無しさん2016/09/28(水) 07:26:06.87ID:6NcLFLen
実は方法が無いわけではない。シングルバイトモードならできる。でも本当にやりたい?
本当に真剣に必要としているなら、このスクリプトでテスト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;
}

833デフォルトの名無しさん2016/10/01(土) 22:37:26.49ID:apxhHWta
やっぱり 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 の時だけエラーになるのだろう。

834デフォルトの名無しさん2016/10/02(日) 00:14:27.80ID:lSw/Qfuv
この記事を見るかぎりではklabaster以外のWindows版gawkでもダメっぽいです
https://groups.google.com/forum/#!topic/comp.lang.awk/coXxXOpeoXU

835デフォルトの名無しさん2016/10/08(土) 21:51:54.06ID:66+5bUgM
>>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にあるように特別な変数として扱われており、リファレンスにも$が演算子で
あることの記載がない。
(続く)

8368352016/10/08(土) 22:00:44.45ID:66+5bUgM
(続き)
ネットの情報。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という変数にフィールドが代入されると説明しているところもあった。そのように理解して
スクリプトを書いてもさして不都合はないだろうな、とは思うが。

837デフォルトの名無しさん2016/10/08(土) 23:11:50.50ID:ZMh6U7O9
広範な調査乙。Gawkのrefcardでもちゃんとoperatorに含まれているなあ。
演算子と明確に認識していなくても、$の後に式OKと思っていれば差し支えなさそう。

838デフォルトの名無しさん2016/10/18(火) 23:10:18.54ID:TQpGgbw6
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・・・残念
}

839デフォルトの名無しさん2016/10/21(金) 17:10:59.85ID:MQQBNMPM
>>756
こういう過疎スレで無駄に突っかかってくるやつむかつくんだが死ね

840デフォルトの名無しさん2016/11/23(水) 00:01:26.03ID:bt3mTQnz
>>839
ブーメランかよwww

841デフォルトの名無しさん2016/11/23(水) 01:18:15.98ID:noM2Pdp3
\おはげだー!/

842デフォルトの名無しさん2016/11/30(水) 02:56:38.28ID:PeC/aWZc

843C初心者2017/02/28(火) 13:18:15.09ID:Mb8mQo1M
awkスクリプトをCソースに変換してコンパイルするための「awka」というツールでできるだけ簡単にUTF−8サポートさせる方法を知りたいです。
ネットで散々調べましたがないようです?

844デフォルトの名無しさん2017/03/02(木) 00:28:53.73ID:CDxvUfiY
このスレも10周年か

845デフォルトの名無しさん2017/03/05(日) 09:28:55.73ID:EQCsqksH
>>843
それがあなたの現在の実力だったということです
お疲れ様でした

846デフォルトの名無しさん2017/03/05(日) 14:45:26.28ID:KmKKYedf
gawkに対応してるなら大丈夫ってことかな?
asciiしか考えていないなら、ソース全チェック…。
要するに、日本語化するんだろうけど。

全然別の言語変換にちょっと咬んだことがあるんだけど、
製品化しちゃってからダブルバイト考慮してないことがわかって、かなり面倒だった。

とりあえず変換してから、ソース見て直すほうが早かったり(笑

がんばってね。

847デフォルトの名無しさん2017/03/06(月) 11:39:31.22ID:FdaYmB9f
awkで $1,$2...$6 こんな出力を↓下にしたいんだけど どうすればいいですかね?
470230
470290

002347
002479

848デフォルトの名無しさん2017/03/06(月) 12:33:46.83ID:FW5jfGh1
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
}'

849デフォルトの名無しさん2017/03/06(月) 15:19:43.83ID:FdaYmB9f
ありがとう
gawk いれないでなんとかならないかな

850デフォルトの名無しさん2017/03/06(月) 17:28:40.15ID:FW5jfGh1
う〜ん、そうなると awk を使わなくてもいいかな

printf '470230\n470290\n' |
while read -r n
do
echo "$n" | grep -o . | sort -n | tr -d '\n'; echo
done

851デフォルトの名無しさん2017/03/06(月) 19:23:27.89ID:08XsJPyW
>>840
だからブーメランとかそういうの関係ないから死ねって言ってんだろカス
死ね

852デフォルトの名無しさん2017/03/06(月) 19:24:30.15ID:08XsJPyW
>>844
粘着が10年位延命しても何もすごくねえよ
突っかかってきたぶちころすぞ雑魚死ね>>840

853デフォルトの名無しさん2017/03/06(月) 19:26:33.18ID:08XsJPyW
>>840
ブーメランとかじゃなくて死ねって言ってんだから死ねボケ

854デフォルトの名無しさん2017/03/07(火) 08:17:48.93ID:6Hf5Xh2e
お疲れ様でした

855デフォルトの名無しさん2017/03/09(木) 21:48:39.65ID:0T9qj2kA
連想配列で
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

856デフォルトの名無しさん2017/03/10(金) 00:18:57.87ID:+B1nKlhG
既に否定されているがgawk4がもし使えたら
awk '{ORS="";PROCINFO["sorted_in"]="@val_num_asc";x=split($0,a,"");for (i in a)print a[i];print "\n"}'

857デフォルトの名無しさん2017/03/10(金) 04:05:38.25ID:wGo6zQ56
最近の gawk ならインクルードファイルが用意されてて join とか使えたり

gawk -vFS= -vOFS= -i join.awk '{split($0,a,"");asort(a);print join(a,1,length(a),SUBSEP)}'

858デフォルトの名無しさん2017/04/04(火) 22:35:43.00ID:9/WMFGSO
# gawk4の読込みタイムアウト機能、けっこう便利そう・・・だけどWindowsはCygwin版じゃないと使えない。残念無念。
BEGIN{
  PROCINFO["/dev/stdin", "READ_TIMEOUT"] = 180000
  print "3分間待ってやる"
  getline t < "/dev/stdin"
  if (t=="バルス") {
    print "ああ…ああ…目があぁぁぁぁぁ〜!"
  }
  else {
    print "時間だ!答えを訊こう!"
  }
}

859デフォルトの名無しさん2017/09/16(土) 00:02:08.63ID:lO9EtkAG
自作の読込みパーサextensionでgz形式のファイルを食えるようにしてみたけど
パーサは一度にひとつしかロードできない設計らしく(ソースでそうなってた)
同じ読込みパーサ形式のxmlライブラリとは併用できなかった
ちょっと使いにくいなあ・・・

860デフォルトの名無しさん2017/10/09(月) 16:41:58.59ID:7/rU/a8H
4.2.0Betaあげ

861デフォルトの名無しさん2017/10/16(月) 14:34:21.07ID:tJ1aGDYb
ファイルの終端関係の謎のエラーに直面
「何で行末が欠ける?分からん、全然分からんぞ!」
と悶えていたら、
いつの間にかvimの設定が変になっていて、
書いたファイルがデフォで行末に\rが来る
ようになっていた。
brew でインストールvimインストールしたとき
妙な設定になったのか?

いやねawkのスクリプトで、
空フィールドが\rになったりとか
macOSなのに変だなあと思っていたのだが…
システム外vim使うときは要注意か。

862デフォルトの名無しさん2017/10/16(月) 14:41:37.20ID:tJ1aGDYb
うぉーっ、林檎のnumbersで書き出したCSVファイルが
DOS改行になっとる…罠だ

863デフォルトの名無しさん2017/10/22(日) 23:24:45.88ID:/qEHJ0vm
お疲れ様でした

864デフォルトの名無しさん2017/10/22(日) 23:26:23.47ID:/qEHJ0vm
>>756
普段話題なく3年も続こうがべつにすごくないね

865デフォルトの名無しさん2017/12/09(土) 10:00:30.84ID:/kecouyU
BEGIN{for(i=1;i<=10000000;i++){printf "%08d", i > "test" } close("test)} の実行にかかる時間を
4.1.4と4.2.0で比較すると、4.2.0のほうが倍近く速くなってるね
fwriteのロックがどうたらの影響なんだろうけど

866デフォルトの名無しさん2017/12/12(火) 21:01:15.07ID:zxiueT/o
懐かしいなぁ。
AWKは自由に現実的な限度はあるけど、書いてて楽しい言語だった。

867デフォルトの名無しさん2018/01/08(月) 11:00:30.57ID:szpKYJOz
お疲れ様でした

868デフォルトの名無しさん2018/01/12(金) 00:18:25.22ID:8Bbkgawk
IDがgawkなので来ました

869デフォルトの名無しさん2018/01/17(水) 10:09:56.59ID:MoHAEd1l
AWKって基本的にUnicodeには対応してるんだよね。
GNUにしろBSDにしろ。

870デフォルトの名無しさん2018/01/17(水) 17:52:56.47ID:MoHAEd1l
置換函数の第二仮引数に[バックスペース][置換対象の文字列]みたいにしたい時は
gsub(/foo/, "\\\\&", $n)
ってしないといけないんだね。
gsub(/foo/, "\\bar", $n)
が foo -> \bar だったんで foo -> \foo は
gsub(/foo/, "\\&", $n)
でいいと思って半時程嵌った。

871デフォルトの名無しさん2018/01/18(木) 07:25:24.80ID:eRgrS92p
>>862
それ勧告に従っただけだと思うが。
http://www.ietf.org/rfc/rfc4180.txt

新着レスの表示
レスを投稿する