X



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/
0729720垢版2013/02/09(土) 15:32:27.55
>>727
>単に一致なら正規表現なんか使わずに比較すればいいじゃん。
意味が分からないんですが、awk上の話ですよね?

>>728
index()の引数は文字列だから、これをうまく使えば目的の処理ができる・・・のかな?

でもなんかawkでごちょごちょやるより、メタ文字をエスケープする前処理をかますなり
何なりしたほうが素直な気がしてきた・・・。たとえばこんな感じで

$ var='hoge$fuga'
$ var2=$( echo "$var" | sed 's/\$/\\\\$/g' ) ←エスケープ処理
$ echo "$var" | awk -v var="$var2" '
$0 ~ var {print var}
END {print var}
'
hoge\$fuga
hoge\$fuga
0730デフォルトの名無しさん垢版2013/02/09(土) 17:49:52.25
/bin/shでごちょごちょやるのが好みなら、awkもfgrepも使わず、case文でやりゃいいんじゃないの。
0732デフォルトの名無しさん垢版2013/02/10(日) 14:31:49.57
>729
いや、その方法でも結局 ' はエスケープが必要でしょ。
ダイレクトにシェル変数に入れる方法か、
ファイルなどに吐き出しておく方法の方が安定。
まぁそれでも改行とか制御文字入れられるともにょる場合があるけどな。
0736デフォルトの名無しさん垢版2013/03/11(月) 10:05:12.56
#
# text converter ( Mac to MS-DOS on Windos/MS-DOS machine)
# convert CR to CR+LF
#
BEGIN{ RS = "\r" }
{ print }
0737デフォルトの名無しさん垢版2013/03/15(金) 08:05:25.28
#
# Line(行数)を数える
#

END { FNR }
0738デフォルトの名無しさん垢版2013/03/20(水) 19:07:17.00
# text to html converter
# usage: awk -f txt2htm.awk infile1.txt > outfile2.html

BEGIN{
print("<html>"); print("<head>")
print("<titile> My favorite URLs </titile>")
print("</head>"); print("<h1> </h1>"); print("<body>");
}

/^[:space:]*http/ { print "<A HREF=\""$1"\">"$1"</A><BR>"}

END{
print("</body>")
print("</html>")
}
0739UNIX(LF) to DOS(CR+LF) conversion垢版2013/03/21(木) 21:15:00.86
awk 1 infile1 > outfile2.txt
0740デフォルトの名無しさん垢版2013/03/21(木) 22:10:08.07
# awk -f add.awk
BEGIN {
  s1 = "323524855"
  s2 = "4972560"

  reverse(a2, s2)
  size = reverse(a1, s1) # s1 > s2
  carry = 0

  for(k = 1; k <= size; k++) { # s1 > s2
    d = a1[k] + a2[k] + carry
    if(d >= 10) {
      e[k] = d - 10
      carry = 1
    } else {
      e[k] = d
      carry = 0
    }
  }

  if(carry == 1) {
    e[k] = 1
    size = k
  }

  g = produce_string(e, size)
  printf("%s + %s = %s\n", s1, s2, g)
  printf("%f\n", s1 + s2)
  exit
}
0741デフォルトの名無しさん垢版2013/03/21(木) 22:11:11.39
# >>740のつづき
function reverse(a, s, k, i) {
  k = 1;
  size = length(s)
  for(i = size; i >= 1; i--) {
    a[k++] = substr(s, i, 1)
  }

  return size
}
function produce_string(a, size, i) {
  g = ""
  for(i = size; i >= 1; i--) {
    g = g a[i]
  }

  return g
}
0743grepをawkで垢版2013/03/22(金) 13:32:02.74
# usage: awk -f grep.awk char1 file1 file2

BEGIN{
pattern = ARGV[1]
ARGV[1] = ""
}
$0 ~ pattern {print($0" File name=" FILENAME)}
0744デフォルトの名無しさん垢版2013/11/30(土) 12:16:25.95
$ echo 10 20 30 | awk '{for(i=0;i<4;)print _$++i}'
10
20
30

_$++iでも$++iでもどちらでもいけるのですが、アンダースコアが付いて何故大丈夫なのでしょうか?
0749デフォルトの名無しさん垢版2014/04/19(土) 13:45:38.45ID:Db2IzPol
とあるgawkスクリプトの先頭で
{last_hoge=hoge; hoge=$ 3}
ってやってるんだけど、
hoge=$ 3はhoge=$3の間違い? それともこういう記法がある?
0754デフォルトの名無しさん垢版2014/04/20(日) 15:12:13.25ID:k3tDznaJ
今はじめて知った。haskellの$は演算子だって知ってたけど、awkでも演算子だったんだね。
0757デフォルトの名無しさん垢版2014/10/21(火) 15:46:10.36ID:TQsAGJgk
質問させてください

今ディレクトリ内のファイルの名称とサイズのリストを作りたいと思っています
コマンドとしてはls -lを実行していますがこれをさらにawkにパイプしています
ただしファイル名にスペースが含まれているため以下のような苦肉の策をとっておりますが

ls -l | awk '{print $5 "\t" $9$10$11$12$13$14$15$16$17$18$19}'

10個以上で区切られてる可能性もあるため根本的な対応をしたいと考えていますが
よい案はありますでしょうか
0758デフォルトの名無しさん垢版2014/10/21(火) 17:25:55.68ID:EsuQiv22
# ファイル名に「"」が含まれていたら知らね。
ls -Ql |awk '{split($0, foo, "\x22"); print $5 "\t" foo[2]}'
0762デフォルトの名無しさん垢版2014/12/14(日) 00:00:31.34ID:7YfznIJB
どちらも非可読文字ですね。そしてそうなるとスレ違い。
awkと絡むのなら具体的にどうぞ。
0763デフォルトの名無しさん垢版2015/02/03(火) 10:36:52.13ID:Dvc0nyMp
Terastationのファイル・ホルダ名に使うとファイルレプリケーションでエラーが起こる文字があって、それを変換するバッチを生成する時にこのマイナー言語が大活躍した。
約80万件のファイルホルダ名から抽出するのに10分程度だった。
0764デフォルトの名無しさん垢版2015/05/26(火) 00:18:03.33ID:Y5HiR/XE
Gawk4.1.2が出たなあ、と思ってたらすぐ4.1.3が出た。
素人には違いがあまり分からんのだが。
0766デフォルトの名無しさん垢版2015/06/03(水) 20:45:34.22ID:vBAc8MUN
>>765
買ってきた。まだ最初の方と最後の方を眺めただけだけど。

ページiv(「はじめに」)でawkの表記について「本書内では、いずれの
場合もすべて小文字のawkという表現に統一しております」と
あるのに、書名がAWK。

巻末のリファレンスで気になったところ。
演算子の優先順位に触れていない、フィールド演算子が
「特別な意味を持つな変数」の中に入れられている。

参考書や文献がないけど、今時は「ネットでググれ」かな。
0767デフォルトの名無しさん垢版2015/07/06(月) 22:02:56.12ID:Wnwr3Nh9
Mono: Playback -9707 [5%] [-97.07dB] [on]
上の行からパーセントを除いた数字(上の例だと5)を取得したいのですがどのようにしたらよいでしょうか?
パーセントの値は0から100の整数だと思います
0771デフォルトの名無しさん垢版2015/07/10(金) 10:45:11.15ID:VcZTZ3UB
テンプレである筈の1が読めないんだが、このスレ的にはPOSIXで書くのが
正統?普段はGawkしか使わないので一応確認。
0772デフォルトの名無しさん垢版2015/10/10(土) 22:36:33.12ID:1AEUTcmG
awk の a は、aho の a

ただし、エイホと読むらしい
へぇーーーーー
0774デフォルトの名無しさん垢版2016/02/18(木) 00:13:16.92ID:E3KgV2Kz
普通は x[3]=5 と書くが、=なしの
x[3]
だけでもエラーとならず、x を配列として確保し、length(x)=1 になるのを発見
まあ、あまり必要ないけど
0778デフォルトの名無しさん垢版2016/02/28(日) 01:02:06.47ID:Atbyv4Wk
IGNORECASE=1
をBEGIN の前に置いてもエラーにならず、不可解動作
セキュリティ的にやばくないの
0779デフォルトの名無しさん垢版2016/02/28(日) 02:01:41.85ID:2mMmSiU+
>>778
BEGIN セクションを先頭に書けとは何処にも書いてない。

BEGIN を最後に書いても END を最初に書いても問題は無い。
何処に書いても、実際には先頭行読み込み前、各行読み込み時、最終行読み込み後にそれぞれ
パターンマッチが行われている。
ただマッチする条件が特殊だから、先頭か最後でしか中の文が実行されないだけ。
0780デフォルトの名無しさん垢版2016/03/29(火) 09:03:58.15ID:/c8bAcK4
サッカーブッシュ日本代表日程ぷあたん(しゅっちょうまいくろ教育長交代)春文執行40代売上差額シュガーチョコ
https://www.youtube.com/watch?v=NDq1QoJY0nY宇ドナルドアナリストパワーストーンコーチングとしまえん
サッカーブッシュ日本代表日程古本屋よしたけしゅっちょうちょこしゅがー
ディーラー税務署天才開発者死亡詰みヨミドクターマイクロサービス不足
サッカーブッシュ日本代表日程ぷあたんシフト光金さかい強制バイト人権侵害問題
春分資源執行ニューヨーク低原価ぼったステーキソルトレイク福岡横浜新橋奴隷課金パチシフト強制バイト問題新潟米センター生残
コスメ24チャリティー隠れ40代生活保護プレイボーイバイトレードいたりあん接待問題
マスコミKARDローンケーオーサービス不足婚活パーティー寄付金執行原発ビジネス
FBIチャイニーズタイホテル売上事務所ガチャ決算ガチャキャンペーン(販売報道陣過激派組織向携帯最新情報提供終了
校長発言細心注意ノートン産廃エラー(著作権クレーム中国反応融資高額教育費)(中国捕鯨団体40代社員サッカーコメント
高額入学金ヤフウ新橋大学ヤフウ新橋理事長FX経費 おじや50代資産ガリバズフィード40代エリート
0781awk命垢版2016/05/10(火) 10:11:56.15ID:qP72K9YB
mawk32.exeで「multibyte char」のメッセージがでて困ってます、何が原因でしょう?
抑止する方法はありますか?
multibyte指定のコマンドラインオプションは無いようなのですが?
0783awk命垢版2016/05/11(水) 00:10:08.64ID:EkexSAUH
>782

データもプログラムもSJISです。
何に反応して multibyte charが出続けるのか不明です。
gawk高速なので満足なのですが、STDERRに multibyte charがで続けるのでうざいし、この出力ぶんだけ速度も低下?
0784デフォルトの名無しさん垢版2016/05/11(水) 00:13:30.76ID:Qn6YFszJ
入力にSJISでない文字が混在していることない?
nkf -s 入力ファイル | awk
で変換したら
0785デフォルトの名無しさん垢版2016/05/11(水) 03:47:08.47ID:6KznZIvs
コードを教えて下さい。
チャレンジしましたが、これではダメです。。
(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
0786デフォルトの名無しさん垢版2016/05/11(水) 04:14:37.49ID:gi9ycYMA
構文がぜんぜん駄目。
{for(i=1;i<=NF;i++)if($i<0){$i=0};print $0;}

「したいことは、〜したいです。」の構文も駄目。典型的なねじれ文。
0790デフォルトの名無しさん垢版2016/05/13(金) 01:56:22.83ID:VtzDMLxe
awk じゃなくてもいいんなら

$ sed 's/-[0-9][0-9]*/0/g' ...

GNU sed なら

$ sed -r 's/-[0-9]+/0/g' ...

でええんちゃう?
0791デフォルトの名無しさん垢版2016/06/22(水) 00:21:13.08ID:X+fwM1CQ
かまぷ 「『シェル芸』に効く AWK処方箋」

エイホ先生「AWKって使い捨ての言語(中略)プラスアルファの処理がやりたいよね。
ただその処理はとても簡単な処理でいい。そこに対して新しいプログラム言語を作っていきたい」

AWKブーム第1世代は「アイドル辞書」で学んだ――日本GNU AWKユーザー会 斉藤さん (1/5):CodeZine(コードジン)
http://codezine.jp/article/detail/9478
2016/06/15 14:00
0792デフォルトの名無しさん垢版2016/06/22(水) 23:46:54.12ID:P+7nG182
やたらと続きは登録して読めと言われてもなあ。
このスレが立った頃からJGAUCのHPが更新されていないってのも凄い。
0793デフォルトの名無しさん垢版2016/08/27(土) 09:20:46.26ID:2q8s4uQl
Windows版のgawkで遊んでたら
for (i=0; i<n; i++) より
for (i=0; i<n; i+=1) のほうが
実行時間が短くなることに気づいた
なんだこりゃ
0794デフォルトの名無しさん垢版2016/09/13(火) 23:56:36.77ID:mfLTwPLq
for(i=1;i<=1000000;i++){a[i]=1}

for(i=1;i<=1000000;i++){a[i]=sprintf("1")}
結果は同じはずなのに、後者は異常にメモリを食う!ふしぎ!
0795デフォルトの名無しさん垢版2016/09/14(水) 00:22:19.58ID:YCeX8Gov
同じじゃないぞ。数値と文字列だ。
ところで、君が使ってる 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
0796デフォルトの名無しさん垢版2016/09/14(水) 22:01:59.31ID:DqYC5LBT
>>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版の問題かも
0797デフォルトの名無しさん垢版2016/09/14(水) 22:50:10.30ID:PWB0Awgu
>>796
OSX El Capitan
gawk 4.1.4

それぞれBEGIN{}に入れたスクリプトを読み込ませて実行。
で前者数十MB、後者3GB超までメモリ使った(アクティビティモニタ)。
0798795垢版2016/09/14(水) 23:40:38.22ID:YCeX8Gov
やってみたよ。環境は 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" に変更してもこんな感じだから数値と文字列の差というわけではなさそう。
0799デフォルトの名無しさん垢版2016/09/14(水) 23:49:14.48ID:YCeX8Gov
ごめん、書き忘れた。

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.
0800デフォルトの名無しさん垢版2016/09/17(土) 08:30:37.61ID:didBD5ba
よく考えたら、メモリの使用量自体じゃなくて、それがどれだけ増えたかが重要だね。
そして、連想配列の構造体とキーに必要な量はどのケースでも同じと考えられる。
つまり、連想配列の要素のための量がどれだけ違うかを直接知ることができるはず。
というわけで、もう一回テスト。

https://ideone.com/mRuFj7
0801デフォルトの名無しさん垢版2016/09/17(土) 08:32:42.20ID:didBD5ba
実行結果

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 のソースコードをハックしてみるか!
0802デフォルトの名無しさん垢版2016/09/17(土) 14:11:27.89ID:IIH0ZjSk
推測だけど、stream, yield, callback、遅延処理かも

データをバッファサイズ分だけ読み込んで処理して、
次のコマンドへ送ったら、それを捨てて、次のデータを読み込むのかも

この方式だとメモリは、バッファサイズ分だけしか使わない
0803デフォルトの名無しさん垢版2016/09/18(日) 10:41:36.96ID:6jI6cHER
ベクターに公開されてるgawk3.1.5(と非公開の3.1.7)、ヘンテコな処理が見つかったのでメモ
このgawkのsystem関数を実行すると、環境変数TMPが指してるフォルダに
@echo off
system関数の引数
という2行が書かれたバッチファイルpip?.bat(?はsystem実行回数+1)というのが作成され
0804デフォルトの名無しさん垢版2016/09/18(日) 10:44:42.56ID:6jI6cHER
・・・いっぺんに書こうとしたらハネられるorz
0805803垢版2016/09/18(日) 10:46:32.08ID:6jI6cHER
(続き)
それを/c pip?.batで起動、完了後にpip?.batを
削除という流れでコマンドが実行される
0806803垢版2016/09/18(日) 10:47:07.98ID:6jI6cHER
(続き)
system関数を使ったスクリプトを同時に1つしか実行しないなら良いけど
2つ以上実行したときはタイミング次第でpip?.batの数字がぶつかり、先に実行した側が
・ コマンドが実行されない
・ コマンドが実行されるけど、完了後に「バッチファイルが見つかりません」が吐かれる
という結果になる

予めcmdの窓ごとにTMPを変えておけば問題ないけど面倒くさい
コマンド | getlineで起動したほうが手っ取り早いと思う
(ただし出力が2KBytes溜まると止まるから適宜リダイレクトする)

でも何でこんな方法でsystem関数を実装したんだろうね(´・ω・`)
0807デフォルトの名無しさん垢版2016/09/18(日) 13:53:41.51ID:EIh/dcA1
tmpfile を使えば、他と重複しない、ランダムな名前のファイルを作れるのに、

どうして使わないのだろう?
0808デフォルトの名無しさん垢版2016/09/18(日) 14:54:02.97ID:KtcAr9oX
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.
0809デフォルトの名無しさん垢版2016/09/18(日) 15:07:54.47ID:KtcAr9oX
でもソースコードを見るかぎり、パイプではそういうことをしてるみたいなんだけど……
ちょっと試してみてくれないかな。

system("dir") | getline

みたいな感じ? よく知らないけど。
0810803垢版2016/09/18(日) 16:19:12.82ID:6jI6cHER
コマンド | getline で起動する場合はpip?.batは作られませんでした
system関数だけpip?.bat経由の模様
klabaster版のwindows用gawk4.1.3だとsystem関数がpip?.batを
作らなかったから、ベクター版固有の動きかなあと思います
0811デフォルトの名無しさん垢版2016/09/18(日) 17:46:00.36ID:KtcAr9oX
ありがとうございます。
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 を使ってる自分には関係ないといってしまえばそれまでですが。
0812デフォルトの名無しさん垢版2016/09/18(日) 19:56:17.75ID:zTPoEkjL
>>811
vectorの配布ファイル内のreadmeにはソースコードの
公開場所を探してるとか、直接連絡すれば渡すとか書いてある。

Windows版、NTあたりから一時ファイル作らずにパイプ動作するように
なったとか、どこかで読んだ気がするけど。
0813デフォルトの名無しさん垢版2016/09/18(日) 22:03:20.37ID:KtcAr9oX
謎は解けた。
ファイルを使ってデータを渡すのはマクロ __DJGPP__ とマクロ __MINGW32__ が
いずれも定義されていない場合らしいです。
Vector のは MINGW なので該当しません。お騒がせしました。
0814デフォルトの名無しさん垢版2016/09/19(月) 11:56:06.00ID:iIvzjj/t
ファイルを経由していても、ストレージに書き込むとは限らない

メモリ上だけに存在する、ファイルもあり得る。
LinuxのRAMディスク、tmpfs とか
0815803垢版2016/09/19(月) 14:26:19.66ID:fDWhtT6v
>>811
情報ありがとうございます。>>803で書いた「ヘンテコな処理」をpc\popen.c内に確認できました。
scriptify関数のtempnam呼んでるところでプロセスIDもつけるなり、細工したいなあ・・・
0816デフォルトの名無しさん垢版2016/09/20(火) 17:00:26.41ID:RIxgZ1yj
先日アクセスできなかった GNU のサイトが復活してたので 3.1.5 のソースコードを入手できました。
やっぱり os_popen からも scriptify を呼んでたみたいですね。4.1.1 のソースコードじゃ判りませんでした。
一応 chdir はアトミックな処理のはずなのでリスク回避に役立つと思いますよ。それ以外に方法がなければ。
chdir したら rmdir も忘れずに。
0817デフォルトの名無しさん垢版2016/09/20(火) 17:06:03.57ID:RIxgZ1yj
間違えた。chdir じゃなくて mkdir です。
0818デフォルトの名無しさん垢版2016/09/22(木) 12:11:24.09ID:nnsRF/zz
>>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 付きでコンパイルしたから増えるかと思ったのに。
まあ、それ以外は一応予想通りではある。
0819デフォルトの名無しさん垢版2016/09/22(木) 23:15:31.17ID:SYBS8P/o
>>793とか
文字列の連結は "A" "B" よりもsprintf("%s%s", "A", "B") の方が速いとか
gawkって結構クセありますね
0821デフォルトの名無しさん垢版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 の中の複雑さを考えれば意外と差は小さいといえる。
フォーマット文字列が定数なら正規表現みたいにコンパイルすれば
高速化できる……のかなあ? 自分でやってみようとは(今はまだ)思わない。
0822デフォルトの名無しさん垢版2016/09/24(土) 23:15:47.76ID:+IiHRmp0
Windowsで使えるawkでUnicodeを正しく処理できる(length("あいう")で3が返ってくる)ものは
Cygwin版とVector版以外に無いでしょうか?
0823デフォルトの名無しさん垢版2016/09/25(日) 10:08:34.07ID:BH82R274
何があったんですか?

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

に書かれているようなことですか? 別の選択肢も一応あるみたいですが。
トランスレータでもいいなら Perl に a2p が同梱されてます。
0824822垢版2016/09/25(日) 14:28:36.60ID:MNlfsMjx
特に困りごとは無いのですが、最新のVer4.1.4やその近辺のバージョンで
Unicodeが正しく処理できるものがあれば、今使っているBruce版3.1.7から
乗り換えたいなあと思いまして。

↓の5年前に書かれた記事の頃より選択肢が増えたりしてたら嬉しいなと・・・。
http://blog.livedoor.jp/corbie/archives/3924154.html
0825823垢版2016/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 がバイト数なのは、単にマルチバイト文字非対応でコンパイルされてるからだと思います。
マルチバイト文字対応版を誰かがリリースしてくれるのを待つか、自分でコンパイルするかですね。
0826デフォルトの名無しさん垢版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 への引越しを強くお奨めします。
0828デフォルトの名無しさん垢版2016/09/27(火) 18:34:39.64ID:BPXrtVfk
Windows Subsystem for Linux (WSL)では、Ubuntu64の実行ファイルが動く。
Linux API を、Windows API へ変換して呼び出す

Ubuntuのパッケージも、apt-getでインストールできる
■ このスレッドは過去ログ倉庫に格納されています

ニューススポーツなんでも実況