コミュニティ/Netnews 斜め読み

トップ 差分 一覧 Farm ソース 検索 ヘルプ RSS ログイン

comp.lang.awk

  • Netnews の comp.lang.awk を適当に日本語訳して抜粋してあります。(本当に適当です)
  • 書き込んだ人の名前の部分はオリジナルの投稿者の名前に変更させていただきましたが、時間までは変更していません。詳しくは、comp.lang.awk を購読していただくか、Google グループの comp.lang.awk などで確認してください。
  • 件数が増えてきたら古いものから順に過去ログに移動します。過去ログは [complangawk] から参照できます。

最近のタイトル一覧

[ 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 ]

comp.lang.awk

お名前
件名
本文

Anyone every implement a mail client in awk? - Joe User (2006年01月30日 23時48分33秒)

gawk の TCP/IP でメールクライアントが使えればどんなに便利かと思っています。

Damn Small Linux をインストールして、TCP/IP で接続可能になっています。

http://groups.google.co.jp/group/comp.lang.awk/browse_thread/thread/46dfac5bbf25d65b/da5e8983ec9fb738?hl=ja#da5e8983ec9fb738


  • gawk のオフィシャルドキュメントに書かれています。 - Juergen Kahrs (2006年01月30日 23時49分44秒)

基本的な動作であれば、16 行でできます。RFC とは異なった SMTP プロトコルで送信することを覚えておけばできます。

  • POP3 で通信するのであれば、以下のようなものもあります。 - William Park (2006年02月01日 00時29分07秒)
  • 送るだけでよいのであれば、以下のようなものがあります。 - John DuBois? (2006年02月01日 00時30分00秒)
echo "This is my test body" | awkmail -pD -s"Test mail" someone@domain.org

のようにして送信することができます。

{{comment}}


  • 何この怒涛の awk スクリプト。(w - hi_saito (2006年02月01日 00時31分59秒)

Match First Sequence in Regular Expression? - Roger L. Cauvin (2006年01月28日 00時19分51秒)

例えば以下のような文字列があります。

"xyz123aaabbaabbbbababbbbaaabb"

"a" の出現する最初または最初に限っていない 3 文字以上連続の正規表現はどうすればいいのでしょうか?

http://groups.google.co.jp/group/comp.lang.awk/browse_thread/thread/b4df4a4f2b0b1296/2411073041183880?hl=ja#2411073041183880


  • 以下のようにしてできます。 - Janis Papanagnou (2006年01月28日 00時20分15秒)
/[^a]aaa[^a]/
  • 以下のようにしてできます。 - Roger L. Cauvin (2006年01月28日 00時21分02秒)
.*?(?<![ab])aaab
  • gawk で以下のようにしてできます。 - Harlan Grove (2006年01月28日 00時22分00秒)
match(s, /^((((a|aa)?[^a]+)*)aaa([^a]|$)){3}/)
  • どうしたいのか分からないのですが…。 - Ed Morton (2006年01月28日 00時23分10秒)
awk 'BEGIN{FS=OFS="aaa"}{sub($1 FS $2 FS,"")}1'

というのを望んでいるのか?

awk -F"aaa" 'NF>3'

のようなのを望んでいるのか分かりません。

  • 正規表現は左から右に必ず一致するので、以下のようにできます。 - Harlan Grove (2006年01月28日 00時24分49秒)
aaa([^a]|$)

普通の awk なら

if (match(s, /^((a|aa)?[^a]+)*aaa([^a]|$)/)) {
  s = substr(s " ", 1, RLENGTH - 4) "<whatever>" substr(s, RLENGTH - 1)
}

のようにして、gawk なら、

gensub(/^(((a|aa)?[^a]+)*)aaa([^a]|$)/, "\\1" "<your replacement string
here>" "\\4", "", s)

のようにできます。

  • 最初にマッチした場所は以下のようにして求まります。 - James (2006年01月28日 00時26分44秒)
$ echo xyzaaaaa123aaabbaa | perl -nle 'print length($`)+1 if
/(?<!a)a{3}[^a]/'
12
  • 上記のものだと最後に "aaa" が来るとマッチしません。 - William James (2006年01月28日 00時27分42秒)
echo xyz123aaabbaabbbababbbaaab|ruby -ne'p $1.size+1 if
/^([^a]*)aaa(?!a)/'

{{comment}}

don't understand the reason why... - Michael Jaritz (2006年01月28日 00時13分37秒)

# make_A_B.awk
BEGIN{
  n_A = 1000
  n_B = 150000
  deci_ascii_min = 33
  deci_ascii_max = 95
  w_length_min = 2
  w_length_max = 4
  for ( i = 1; i <= n_A; i++ ) {
    str = ""
    w_length = roll(w_length_min, w_length_max)
    for ( j = 1; j <= w_length; j++ ) {
      rand_int = roll(deci_ascii_min, deci_ascii_max)
      chr = sprintf( "%c", rand_int )
      str = str chr
    }
    print str > "A.txt"
  }
  for ( i = 1; i <= n_B; i++ ) {
    str = ""
    w_length = roll(w_length_min, w_length_max)
    for ( j = 1; j <= w_length; j++ ) {
      rand_int = roll(deci_ascii_min, deci_ascii_max)
      chr = sprintf( "%c", rand_int )
      str = str chr
    }
    print str > "B.txt"
  }
}

function roll(m, n) { return m + int(rand() * n ) }

After running "gawk -f make_A_B.awk" there are my two Input-Files A.txt
with 1000 lines and B.txt with 150000 lines for example.

# check_AB.awk
{
  if ( FILENAME == "B.txt" ) {
    if ( $0 in b_array ) {
      val = b_array[$0]
      b_array[$0] = val + 1
    }
    else {
      b_array[$0] = 1
    }
  }
  else {
    i_a++
    array_a[i_a] = $0
  }

}

END{
  for ( i = 1; i <= i_a; i++ ) {
    val_a = array_a[i]
    if ( val_a in b_array ) {
      count = sprintf("%6s", b_array[val_a]) " x in B  " val_a
      print count > "A_checked_against_B.txt"
    }
    else {
      print "               " val_a > "A_checked_against_B.txt"
    }
  }
  close("A_checked_against_B.txt")

  command = "sort > counted_B_sorted.txt"
  for ( i_b in b_array ) {
    val_b = b_array[i_b]
    print sprintf("%6s", val_b) " x " i_b | command
  }

}

Windows 98 SE で gawk 3.1.3 を使っています。

gawk -f check_AB.awk B.txt A.txt

を実行して、A_checked_against_B.txt の結果は問題ありません。counted_B_sorted.txt の結果が変なのですが、どうしてでしょうか?

http://groups.google.co.jp/group/comp.lang.awk/browse_thread/thread/5f16103a31e5bdaf/39dd157f8627b006?hl=ja#39dd157f8627b006


  • roll() が変なのではないでしょうか? - Harlan Grove (2006年01月28日 00時14分39秒)
function roll(m, n) { return m + int(rand() * (n - m + 1)) }

となるはずです。

また、問題の場所は Windows 98 のパイプによるものだと思われます。

  for (i_b in b_array) printf("%6s x %s\n", b_array[i_b], i_b) >
"bcs_temp.txt"
  close("bcs_temp.txt")
  system("sort bcs_temp.txt > counted_B_sorted.txt")
}

のようにしてみてください。

{{comment}}

set word length - venki.slm (2006年01月26日 01時38分06秒)

 1) testcase1 : Testing long attribute                    :: Passed
 2) testcase2 : Testing longlong attribute              :: Passed
 3) testcase3 : Testing double                             :: Passed
 4) testcase4 : Testing long double attribute         :: Failed

のような出力がしたいのですが、

1) testcase1 : Testing long attribute :: Passed
2) testcase2 : Testing longlong attribute  :: Passed
3) testcase3 : Testing double :: Passed
4) testcase4 : Testing long double attribute :: Failed

となってしまいます。

=================wrap.awk=========
BEGIN {if (MAXWIDTH == 0) MAXWIDTH = 80}
{
    while (length($0) > MAXWIDTH)
    {
        for (k = MAXWIDTH; k > 2; --k)
            if (substr($0,k,1) == " ") break
        if (substr($0,k,1) == " ")
        {
            print substr($0,1,k-1)
            $0 = PREFIX substr($0,k+1)
        }
        else # no breakpoint found
        {
            print $0
            $0 = ""
        }
    }
    print $0
}
=================================

http://groups.google.co.jp/group/comp.lang.awk/browse_thread/thread/aa9b3fc60863810d/e2d827ca786ab2d1?hl=ja#e2d827ca786ab2d1


{{comment}}

Mathing a Value and printing out a column for that value - esimbo (2006年01月25日 00時29分59秒)

jane, peter,charles
1,2,3
4,5,6

のようなファイルがあり、結果として、

peter
2
5

のようなものを取得したいと考えています。

awk -v なんとか

のようにしてできると思うのですが、どうすればいいのでしょうか?

http://groups.google.co.jp/group/comp.lang.awk/browse_thread/thread/f83dd7c16008e541/2f0f82c85f2f4205?hl=ja#2f0f82c85f2f4205


{{comment}}

Simple one-liner - Dale Kerr (2006年01月25日 00時20分31秒)

awk '$1 == "ABC"' testfile | awk '{print $NF}'

という一行野郎をどうやれば以下のように変更できますか?

awk '$1 == "$VAR"' testfile | awk '{print $NF}'

つまり、ABC を変数にしたいのです。

http://groups.google.co.jp/group/comp.lang.awk/browse_thread/thread/f4bb454249fb772d/995ba15836f8cb5b?hl=ja#995ba15836f8cb5b


  • 以下のようにします。 - Chris F.A. Johnson (2006年01月25日 00時20分50秒)
awk -v var="$VAR" '$1 == var { printf $NF }' testfile
  • printf() ではなく、print ですね。 - Ed Morton (2006年01月25日 00時22分18秒)

また、以下のところが参考になると思います。

  • 以下のようにしてもできます。 - William James (2006年01月26日 01時33分22秒)
awk 'BEGIN{ARGC--} $1==ARGV[2] {print $NF}' testfile "$VAR"
awk '$1==var {print $NF}' var="$VAR" testfile

{{comment}}

gawk record and field - Mr_Bill (2006年01月18日 01時37分43秒)

以下のようなファイルがあります。

field field field field
field field field
field field field
field field field
field field field field field

最初と最後のレコードは異なった処理をします。

最初の部分は、

<TABLE><TABLEHEADER>$0</TABLEHEADER>

真ん中の部分は、

<TR><TD>$1</TD><TD>$2</TD><TD>$3</TD></TR>

最後の部分は、

<TR><TD>$1</TD><TD>$2</TD><TD>$3</TD></TR></TABLE>

とします。

$myvariable を HTML ファイルに変換するにはどうすればいいでしょうか?

http://groups.google.co.jp/group/comp.lang.awk/browse_thread/thread/55f7bc7b516ae6e0/a963ecfa919b9c3d?hl=ja#a963ecfa919b9c3d


  • NR で分けることができます。以下を試してみてください。 - Ed Morton (2006年01月18日 01時38分15秒)
echo "$myvariable" | awk '
NR==1 { printf "<TABLE><TABLEHEADER>%s</TABLEHEADER>",$0; next }
      { printf "\n<TR><TD>%s</TD><TD>%s</TD><TD>%s</TD></TR>",$1,$2,$3 }
END   { print "\n</TABLE>" }
'
  • 実際にやりたいことは以下のようなことです。 - Mr_Bill (2006年01月18日 23時22分09秒)

$3 は PDF ファイルの名前です。これを images ディレクトリの中にコピーします。$2 はファイルへのリンクです。

{ printf "\n<TR><TD>%s</TD><TD><A HREF="/images/%s">%s</A></TD>",$1,$3,$2 }

うまく、リンクすることができません。

  • 以下のようにするとコピーできます。 - Ed Morton (2006年01月18日 23時24分31秒)
system("cp "$3" /images/"$3)

または、

print "cp "$3" /images/"$3 | "/bin/sh"

でできますが、これがベストとは限りません。

上記 URL を読んで、shell と合わせるのがよいと思います。

{{comment}}

AWK command help - wotm (2006年01月17日 23時03分37秒)

変数を読み込んだ後に以下のようなファイルを実行しました。

awk '{if($1~/^ "$code"/) print $0 }' LCADPIN"$file".2006"$mo""$day"* >
$ADPIN/ADPIN

$code の部分に WZN を加え、うまく動作しています。LCADPIN レコードの最初の部分で ^ の後にスペースを加えようとして、$code をシングルクォートにしようとしています。

http://groups.google.co.jp/group/comp.lang.awk/browse_thread/thread/e792fb03239a7113/1dd46a89a493f65b?hl=ja#1dd46a89a493f65b


  • shell から awk を呼んでいますが、以下にまず目を通してください。 - Ed Morton (2006年01月17日 23時04分14秒)

{{comment}}

Extract specific records from input file - rajesh0310 (2006年01月16日 22時33分45秒)

in-data.txt に 172096 のレコードがあり、レコードの長さは 1024 byte です。21872 のレコードがエラーで er-no ファイルに記載されています。10 文字でエラーナンバーを付けた入力ファイルからエラーを抜粋したいのですが、可能ですか?

http://groups.google.co.jp/group/comp.lang.awk/browse_thread/thread/7795a87af947bb7d/8dfae771a7b22d6d?hl=ja#8dfae771a7b22d6d


  • どうしたいのかクリアになっていない部分もありますが、以下のような感じでしょうか? - Ed Morton (2006年01月17日 00時34分09秒)
awk 'NR==FNR{errs[$0];next}{seq=substr($0,1,10)}seq in errs' 'er-no'
'in-data.txt'
  • er-no ファイルは以下のようになっています。 - rajesh0310 (2006年01月17日 22時55分21秒)
1
5
7
10

また、入力ファイルは 25 のレコードをもっています。10 文字というのは、000000001 や 000000010 のように 10 桁の数字です。

  • まず、10 桁の数字は以下のようにして得られます。 - Ed Morton (2006年01月17日 22時57分32秒)
awk 'BEGIN{val=9;printf "%010d\n",val}'

出力ファイルは awk では以下のようにして得られます。

awk 'BEGIN{val=9;printf "%010d\n",val > "somefile"}'

OS が分からないのですが、UNIX の shell であれば、以下のようにもできます。

awk 'BEGIN{val=9;printf "%010d\n",val}' > "somefile"

{{comment}}

Inserting lines at top and bottom of file - eldiabloinfernal (2006年01月15日 01時40分53秒)

以下のようなファイルの最初と最後にテキストを挿入したいのです。

-----top of file -----------

<insert start line here>
abcd
defg
hijk
lmno
<insert end line here>

-----e bottom of file ----------

今は

cat (file1 file2 file3) > file

としています。

http://groups.google.co.jp/group/comp.lang.awk/browse_thread/thread/be0ca68dd92dd602/027519c86faa274d?hl=ja#027519c86faa274d


  • 以下のようにします。 - Ed Morton (2006年01月15日 01時41分24秒)
awk 'BEGIN{print "start"}1;END{print "end"}' file

UNIX shell であれば、以下のようにします。

echo "start"; cat file; echo "end"

{{comment}}

odd row and numbering with difference 20 - Beta (2006年01月15日 01時35分11秒)

奇数行だけを抜き出して、20 を加えて行きたいのです。

http://groups.google.co.jp/group/comp.lang.awk/browse_thread/thread/b7fd75bbfc195cb8/6dc2520357f09737?hl=ja#6dc2520357f09737


  • 以下のようなことを言っていますか? - Ed Morton (2006年01月15日 01時35分46秒)
$ cat file
1
2
3
4
5
6
7
8
9
$ awk 'NR%2{print c+=20,$0}' file
20 1
40 3
60 5
80 7
100 9

{{comment}}

Using igawk as the interpreter of a script on Linux - Joe User (2006年01月15日 01時24分48秒)

#!/bin/bash
if [[ "$0" != "/bin/igawk" ]] ; then exec /bin/igawk --file <(sed '2s/./#/' "$0") "$@"; fi; exit

の 2 行が igawk に必要な気がします。

http://groups.google.co.jp/group/comp.lang.awk/browse_thread/thread/2720ff2e8914227f/3dd35f8873d7adc4?hl=ja#3dd35f8873d7adc4


  • xgawk では igawkgawk の機能として含まれますので、こちらの方がよいでしょう。 - Andrew Schorr (2006年01月15日 01時25分48秒)
  • 問題ないようですが、気が付いた点があります。 - Joe User (2006年01月15日 01時27分25秒)
  1. ここにあるのは 10 ヶ月も前のα版です。
  2. Mandrake に含まれるものの倍以上のバイナリの大きさです。

これは gawk に組み込まれるのですか?

  • 以下のようになっています。 - Andrew Schorr (2006年01月15日 01時29分02秒)
  1. 現在 gawk 3.1.5 にパッチを当てたものをリリースしようとしています。また、ステータスをβにしました。最新版は cvs から入手できます。
  2. スタティックでビルドしましたか? 手元のものは 276 KB です。
  3. どうなるかは分かりませんが、メンテナーはこのプロジェクトの存在を知っています。明確なスケジュールは明らかになっていません。
  • 以下のようにしてみてください。 - Juergen Kahrs (2006年01月15日 01時33分00秒)
make install-strip

約 280 KB です。

{{comment}}

how should printf "%d",x behave when x is a very large value? - Andrew Schorr (2006年01月15日 01時02分31秒)

awk -v n=100 'BEGIN {printf "%d\n",2^n}'

のような場合に、1267650600228229401496703205376 のように出力するのと、浮動小数点近似で表示するのとどちらが良いでしょうか?

また、どこで近似と切り替えるのが望ましいのでしょうか?IEEE では 2^53 あたりで切り替えます。

http://groups.google.co.jp/group/comp.lang.awk/browse_thread/thread/27c7ff977ea4a4fe/73ebc6bc073d7fc6?hl=ja#73ebc6bc073d7fc6


  • プラットフォームの整数に合わせるというのも良いかもしれません。聞きたいのは、どういう方法が最もロジカルかということです。 - Andrew Schorr (2006年01月15日 01時03分49秒)
  • %d の挙動は常に %d であって欲しい。 - John DuBois? (2006年01月15日 01時07分03秒)
  • awk では倍精度計算なので、上記はそれを超えてしまっています。 - Harlan Grove (2006年01月15日 01時09分31秒)
  • %d は %.0f と同じということを言っていますか? - Andrew Schorr (2006年01月15日 01時10分51秒)
  • そうです。 - Harlan Grove (2006年01月15日 01時11分11秒)
  • %.0f にするのが最も簡単な解と思います。 - Don Stokes (2006年01月15日 01時12分06秒)
[don@bsd ~]$  gawk 'BEGIN { printf "%d\n", 2^63 }'
9223372036854775808
[don@bsd ~]$  gawk 'BEGIN { printf "%d\n", 2^64 }'
0
[don@bsd ~]$  gawk 'BEGIN { printf "%d\n", 2^65 }'
3.68935e+19
[don@bsd ~]$  gawk 'BEGIN { printf "%.0f\n", 2^63 }'
9223372036854775808
[don@bsd ~]$  gawk 'BEGIN { printf "%.0f\n", 2^64 }'
18446744073709551616
[don@bsd ~]$  gawk 'BEGIN { printf "%.0f\n", 2^65 }'
36893488147419103232
  • 2^64 が 0 になるのは known bug で、議論している ML でパッチが入手できます。 - Andrew Schorr (2006年01月15日 01時14分04秒)

{{comment}}

how should "inf" and "nan" be converted to numeric values? - Andrew Schorr (2006年01月15日 00時36分38秒)

以下のような awk スクリプトがあります。

awk 'BEGIN {print "nan"+0,"-nan"+0,"inf"+0,"-inf"+0}'

IEEE の値として扱えば、

nan nan inf -inf

のような値が出力されるでしょう。また、古い awk なら、

0 0 0 0

のような値が出力されるでしょう。

どちらで出力されるのが良いでしょうか?ユーザーでオプション指定するのも方法のひとつです。

http://groups.google.co.jp/group/comp.lang.awk/browse_thread/thread/ae59c47f2e5562d9/f7587ee1b83494c9?hl=ja#f7587ee1b83494c9


  • それが文字列なのか、数値なのかを見極めるのは難しいと思います。 - Janis Papanagnou (2006年01月15日 00時37分30秒)
  • IEEE standard 1003.1 を見ると全て 0 で良いと思います。 - Ed Morton (2006年01月15日 00時38分33秒)

でも全ての awk で同じ挙動を示しているわけではありません。

$ /usr/bin/awk 'BEGIN {print "nan"+0,"-nan"+0,"inf"+0,"-inf"+0}'
0 0 0 0
$ /usr/xpg4/bin/awk 'BEGIN {print "nan"+0,"-nan"+0,"inf"+0,"-inf"+0}'
0 0 0 0
$ nawk 'BEGIN {print "nan"+0,"-nan"+0,"inf"+0,"-inf"+0}'
NaN -NaN Inf -Inf
$ gawk 'BEGIN {print "nan"+0,"-nan"+0,"inf"+0,"-inf"+0}'
0 -NaN 0 -Inf
$ gawk --posix 'BEGIN {print "nan"+0,"-nan"+0,"inf"+0,"-inf"+0}'
0 -NaN 0 -Inf
$ gawk 'BEGIN {print "+nan"+0,"-nan"+0,"+inf"+0,"-inf"+0}'
NaN -NaN Inf -Inf
$ gawk --posix 'BEGIN {print "+nan"+0,"-nan"+0,"+inf"+0,"-inf"+0}'
NaN -NaN Inf -Inf

gawk では IEEE Standard 754 に従うことが書かれています。

"On systems supporting IEEE 754 floating point format, values
representing negative infinity are formatted as `-inf' or `-infinity',
and positive infinity as `inf' and `-infinity'. The special \223not a
number\224 value formats as `-nan' or `nan'."

これが全てのキーになりそうです。

  • そこには以下のように書かれています。 - Andrew Schorr (2006年01月15日 00時43分14秒)
A string value shall be converted to a numeric value by the
equivalent of the following calls to functions defined by the
ISO C standard:
 setlocale(LC_NUMERIC, "");
 numeric_value = atof(string_value);

atof を見ると strtod と同じと書いてあり、strtod を見ると、IEEE の特別文字列であることが書かれてあります。

また、ここでは規格の議論ではなく、どちらが良いのかを話し合いたいと思っています。

  • 分かりましたが、規格を変更するのは大変な作業ですよ。 - Ed Morton (2006年01月15日 00時46分37秒)
  • 以下のようなことを言っていますか? - Ed Morton (2006年01月15日 00時48分46秒)

文字列だと以下のようになります。

$ echo "Hello, my name is Nan." | nawk '{for (i=1;i<=NF;i++) printf "%s
-> %d\n",$i,$i+0}'
Hello, -> 0
my -> 0
name -> 0
is -> 0
Nan. -> 2147483647

数値だと以下のようになります。

$ echo "1 2 NAN 3 4" | nawk '{for (i=1;i<=NF;i++) printf "%s ->
%d\n",$i,$i+0}'
1 -> 1
2 -> 2
NAN -> 2147483647
3 -> 3
4 -> 4

gawk のアプローチは以下のようになっています。

$ echo "1 2 NAN 3 4" | gawk '{for (i=1;i<=NF;i++) printf "%s ->
%d\n",$i,$i+0}'
1 -> 1
2 -> 2
NAN -> 0
3 -> 3
4 -> 4

これを以下のようにすると言っていますか?

$ echo "+1 nan -2 +nan +3 -nan -4" | gawk '{for (i=1;i<=NF;i++) printf
"%s -> %d\n",$i,($i~/^[+-]/?$i:"+"$i)}'
+1 -> 1
nan -> NaN
-2 -> -2
+nan -> NaN
+3 -> 3
-nan -> -NaN
-4 -> -4
  • %d ではなく %f です。 - Andrew Schorr (2006年01月15日 00時53分28秒)
echo "Hello, my name is Nan." | nawk '{for (i=1;i<=NF;i++) printf "%s
-> %.0f\n",$i,$i+0}'
Hello, -> 0
my -> 0
name -> 0
is -> 0
Nan. -> NaN

以下のスクリプトを実行すれば分かるとおもいます。

BEGIN {
   inf = 2^1025
   infstr = sprintf("%f",inf)
   printf "2^1025 = %s\n",infstr
   if (inf != infstr+0)
      printf "%f+0 != %s+0\n",inf,infstr
}

Solaris/nawk では、

2^1025 = Inf

Solaris/gawk では、

2^1025 = Inf
Inf+0 != Inf+0

Linux/gawk では、

2^1025 = inf
inf+0 != inf+0

となります。どらが最も望ましいでしょうか?

{{comment}}

print a regexp grouping - Mr R G Shepherd (2006年01月15日 00時24分30秒)

以下のような入力ファイルがあります。

319-009-i1-nr0-mx15.log
319-009-i1-nr0-mx12.log
319-009-i1-nr0-mx9.log
319-009-i1-nr0-mx6.log
319-009-i1-nr0-mx3.log

これから以下のものを出力します。

15
12
9
6
3
awk '/mx([0-9]+)\./ { print <WHAT> }'

のようにするのですが、<WHAT> の部分はどうすればいいのでしょうか?

http://groups.google.co.jp/group/comp.lang.awk/browse_thread/thread/678bd97bb32f059f/269b1e92c1f6321c?hl=ja#269b1e92c1f6321c


  • 以下の 2 つの方法があります。 - Ed Morton (2006年01月15日 00時24分59秒)
awk '/mx([0-9]+)\./{sub(/.*mx/,"");sub(/\..*$/,"");print}'
gawk '/mx([0-9]+)\./{print gensub(/.*mx([0-9]+).*/,"\\1","")}'

他にも split() や match() や index() を使った解法もあります。

gawk を使っているのであれば、以下の書籍を読まれることをお勧めします。

  • 以下のようにできます。 - Kenny McCormack? (2006年01月15日 00時27分13秒)
awk '/mx([0-9]+)\./{sub(/.*mx/,"");sub(/\..*$/,"");print}'

という部分は、

sub(/.*mx/,"") {print $0+0}

ということですよね。

  • 全てがそれでうまくいくとは限りません。 - Ed Morton (2006年01月15日 00時29分50秒)
awk '/mx([0-9]+)\./{sub(/.*mx/,"");print $0+0}'

のようにできるかもしれませんが、

319-009-mx-nr0-mx15.log

といった場合には困ってしまいます。

  • 以下のようにしてもできます。 - Bill Seivert (2006年01月15日 00時31分24秒)
{
     mat = match ($0, /mx[0-9][0-9]*/);
     if (mat) {
         print substr ($0, RSTART + 2, RLENGTH - 2);
     }
}
  • FS を使ったゲームで以下のようにもできます。 - Harlan Grove (2006年01月15日 00時32分48秒)
awk '{ print $2 }' FS='mx|\\.' yourfilename

{{comment}}

Using external functions in AWK - srikar2097 (2006年01月15日 00時15分24秒)

awk ではなく、shell で書かれた外部関数を awk で呼び出すことができません。

http://groups.google.co.jp/group/comp.lang.awk/browse_thread/thread/88cd0a37715be00f/e422e62be4d4f183?hl=ja#e422e62be4d4f183


  • TAWK では可能ですが、現在 TAWK は入手できません。 - Doug McClure? (2006年01月15日 00時16分20秒)
  • awk は system() 関数で呼び出すことは可能ですが、その一部を呼び出すことはできません。 - Ed Morton (2006年01月15日 00時18分00秒)

{{comment}}

print statement and punctuation - Jeff Higgins (2006年01月14日 23時58分13秒)

print {
    (desired output goes here...)
} > c:/test/java/$2.java

としたのですが、思ったように動作しません。

入力は

254 NewSubfileType Type.LONG              A general indica...
255 SubfileType    Type.SHORT             A general indica...
256 ImageWidth     Type.SHORT , Type.LONG The number of co...

で、出力は以下のようなものです。

package higgins.jeff.geotiff;

import java.util.ArrayList;

public class Artist extends TagMeta {

  public $2() {
    super();
  }

  public $2(Integer ifdTag, Integer ifdType, Integer ifdValue, Integer
ifdCount){
    super(ifdTag, ifdType, ifdValue, ifdCount, ifdPosition);
  }

  @Override
  public String toString() {
    return name;
  }

  @Override
  public Integer toInteger() {
    return tag;
  }

  @Override
  public String toHexString() {
    return Integer.toHexString(tag);
  }

  @Override
  public String getShortDescription() {
    return shortDescription;
  }

  @Override
  public void initialize(TiffFileReader reader, ArrayList<Byte> array) {

  }

  private final Integer tag = $1;

  private final String name = "$2";

  private final EnumSet<Type> types = EnumSet.of( $3 $4 );

  private final String shortDescription = "$5";
}

http://groups.google.co.jp/group/comp.lang.awk/browse_thread/thread/541831b3465b9a30/c87014a946e9ab30?hl=ja#c87014a946e9ab30


  • まず、やりたいことは以下のようなことですか? - Ed Morton (2006年01月14日 23時58分48秒)
print "text" > "c:/test/java/" $2 ".java"

であれば、以下のようにしてみてください。

printf "public %s() {\n\tsuper();\n}\n",$2 > "c:/test/java/" $2 ".java"
  • 以下のようにしてみました。 - Jeff Higgins (2006年01月15日 00時00分16秒)
BEGIN{FS = "\t|"}
{
printf("package higgins.jeff.geotiff;\n") > "c:\\test\\java\\"$2".java"
printf("import java.util.ArrayList;\n") >> "c:\\test\\java\\"$2".java"
printf("public class Artist extends TagMeta {\n\n") >>
"c:\\test\\java\\"$2".java"
printf("\tpublic "$2"() {\n") >> "c:\\test\\java\\"$2".java"
printf("\t\tsuper();\n") >> "c:\\test\\java\\"$2".java"
printf("\t}\n\n") >> "c:\\test\\java\\"$2".java"
}
  • 以下のようにしてみてください。 - Ed Morton (2006年01月15日 00時01分43秒)
  1. ">>" と ">" は、awk では区別はありません。
  2. ファイルを最後にクローズした方が良いでしょう。
  3. 毎回ファイル名を指定するよりも一度だけの指定の方が良いでしょう。
BEGIN{FS = "\t|"}
{
outfile = "c:\\test\\java\\"$2".java"
printf("package higgins.jeff.geotiff;\n") > outfile
printf("import java.util.ArrayList;\n") > outfile
printf("public class Artist extends TagMeta {\n\n") > outfile
printf("\tpublic "$2"() {\n") > outfile
printf("\t\tsuper();\n") > outfile
printf("\t}\n\n") > outfile
close(outfile)
}
  • ファイルの同時オープンに限界があるので、限界があった時には ">" ではなく ">>" の方が良いでしょう。 - Bill Seivert (2006年01月15日 00時05分08秒)
  • 検証するために以下のようなファイルを作成してみました。 - Jeff Higgins (2006年01月15日 00時07分03秒)
data01 This is line 1 of data01.
data01 This is line 2 of data01.
data02 This is line 1 of data02.
data02 This is line 2 of data02.
data01 This is line 3 of data01.
data02 This is line 3 of data02.
data01 This concludes the test of data01.
data02 This concludes the test of data02.
data03 Good Afternoon!

テストしたのは以下のものです。

BEGIN {FS = "\t"}
{
  printf ($2) > "c://test//java//"$1
  close(outfile)
}
data01
This is line 1 of data01.
This is line 2 of data01.
This is line 3 of data01.
This concludes the test of data01.

data02
This is line 1 of data02.
This is line 2 of data02.
This is line 3 of data02.
This concludes the test of data02.

data03
Good Afternoon!

上のようにはならず、以下のようになります。

data01:
This concludes the test of data01.

data02:
This concludes the test of data02.

data03
Good Afternoon.
  • 以下のようにしないとファイルを閉じていることになりません。 - Kenny McCormack? (2006年01月15日 00時11分28秒)
  printf ($2) > (outfile = "c:/test/java/"$1)
  close(outfile)
  • 以下のようにすることで思っていたとおりのことができました。 - Jeff Higgins (2006年01月15日 00時12分27秒)
BEGIN {FS = "\t"}
{
  printf ($2) > "c://test//java//"$1
  close("c://test//java//"$1)
}

{{comment}}

Processing columns instead of rows - mickey (2006年01月11日 00時58分54秒)

以下のようなファイルがあります。

ACGTAC
AGTCGT
ACGA?T
GTACGT

この出力は以下のようなものです。

000111
011000
0001?0
111000

それぞれの文字列が、各列でいくつあるかをカウントするようなものです。ただし、ファイルは 2 GB くらいあります。

http://groups.google.co.jp/group/comp.lang.awk/browse_thread/thread/0dc4bfba854733ef/408bd1c56a802202?hl=ja#408bd1c56a802202


  • 以下のような map.awk を作ってみました。 - Ed Morton (2006年01月11日 00時59分48秒)
BEGIN{FS=OFS="";keep="?";ARGV[ARGC++]=ARGV[1]}
NR==FNR {
     for (i=1; i<=NF; i++) {
         if ($i != keep) {
             cnt[i,$i]++
             if (cnt[i,$i] > maxCnt[i]) {
                 maxVal[i] = $i
                 maxCnt[i] = cnt[i,$i]
             }
         }
     }
     next
}
{
     for (i=1; i<=NF; i++)
         if ($i != keep)
             $i = ($i == maxVal[i] ? 0 : 1)
}
1

{{comment}}

FTP in gawk - Todd Coram (2006年01月11日 00時48分35秒)

gawk で ftp の put を実装しようとしています。

BINMODE を使って、

printf("") |& dataport;

としようとしていますが、何も送られません。

#!/usr/bin/gawk -f
#
# ftpput - put files via ftp
#
# Author: Todd Coram (todd at maplefish DOT com).
# Version:  0.9    1/9/2006
#
# A simple ftp file "put" transfer script. If a -d is supplied then try
and
# make the directories that are part of each file's filepath. 'rootdir'
is the remote
# FTP server directory to CWD to before starting the transfers.
#

BEGIN {
  if (ARGC < 5) {
    print "Usage: ftpput [-d] host user rootdir password file1 ..
fileN" \
      >"/dev/stderr";
    exit 1
  }

  # The record separator is set to a string that should
(statistically?)
  # not occur even in binary data (ha!). We append a pid so that this
  # app can transfer itself (makes the separator dynamic).
  #
  BinRS="yummydeadbeaf" PROCINFO["pid"];

  Verbose=1;
  RS = ORS = "\r\n";

  mkdir = (optidx = (ARGV[1] == "-d") ? 2 : 1) - 1;
  host = ARGV[optidx++]
  user = ARGV[optidx++]
  pass = ARGV[optidx++]
  rootdir = ARGV[optidx++]

  Ftphost = "/inet/tcp/0/" host "/21";
  expect("", "220");
  if (expect("USER " user, "331|230") ~ "^331") {
    expect("PASS " pass, "230");
  }
  expect("TYPE I", "200");
  expect("CWD " rootdir, "200|250");

  for (; optidx < ARGC; optidx++) {
    if (mkdir) mkdirhier(ARGV[optidx]);
    pasv_send(ARGV[optidx]);
  }

  expect("QUIT", "221");

}

function mkdirhier(file,   part,pidx,pcnt,dir) {
  pcnt = split(file, part, "/")
  for (pidx = 1; pidx < pcnt; pidx++) {
    dir = (pidx == 1) ? part[pidx] : dir "/" part[pidx];
    expect("MKD " dir, "250|257|521");
  }

}

function pasv_send(file, ln,oldrs,oldbinmode,addr,port,dataport) {
  ln = expect("PASV", "227");
  if (!match(ln,
/([0-9]+),([0-9]+),([0-9]+),([0-9]+),([0-9]+),([0-9]+)/,aa)) {
    print "Couldn't parse connection information from " ln
>"/dev/stderr";

    exit 1;
  }
  addr = aa[1] "." aa[2] "." aa[3] "." aa[4];
  port = (aa[5]*256)+aa[6];
  dataport = "/inet/tcp/0/" addr "/" port;
  printf("") |& dataport; # force connection open

  expect("STOR " file, "150");
  if (Verbose) printf(" *  Sending %s to %s\n", file, dataport)

>"/dev/stderr";

  oldrs = RS;  RS = BinRS; ORS = "";
  oldbinmode = BINMODE;  BINMODE="rw";

  while ((getline ln <file) > 0) {
    print ln |& dataport; fflush(dataport);
  }
  close(dataport);
  close(file);

  RS = ORS = oldrs;
  BINMODE = oldbinmode;

  expect("","226");

}

function expect(query,code,  line, a) {
  if (query != "") {
    print query |& Ftphost;
    if (Verbose) printf("Sending: %s\n", query);
  }
  Ftphost |& getline line;
  if (Verbose)   printf("    Got: %s\n", line);
  if (match(line,"^(" code ")",a)) {
    return line;
  }
  printf("ERROR on (%s): Expected (%s). Got %s\n",
         query, code, line) > "/dev/stderr";
  exit 1;

}

http://groups.google.co.jp/group/comp.lang.awk/browse_thread/thread/d781e1b910f98583/51f2633a99354616?hl=ja#51f2633a99354616


  • BINMODE は non-POSIX の場合のみ有効です。 - Juergen Kahrs (2006年01月11日 00時49分25秒)
  • 全てを awk でやるチャレンジはいいのですが、時間の無駄になる可能性があります。また、shell で実行すれば簡単になると思われる部分もあるので、comp.unix.shell に投稿してみてはどうでしょうか? - Ed Morton (2006年01月11日 00時51分39秒)
  • バイナリファイルを読むのは xgawk では簡単にできます。 - Andrew Schorr (2006年01月11日 00時54分33秒)
$ xgawk -lreadfile 'BEGIN { s =
readfile("/boot/vmlinuz-2.6.10-0.ti.4.fc1smp"); printf "%s", s}' | diff
/boot/vmlinuz-2.6.10-0.ti.4.fc1smp -

{{comment}}

Running AWK serially - Lurker (2006年01月11日 00時30分56秒)

uniq を計上している時に不思議な現象が発生します。

awk -f scripts/find_slice_values.awk fieldname="genre" `find catalog
-type f -name machine.txt` | sort | uniq
 [11]ic_design
graphic_design [8]
 [2]stration
illustration [2]

machine.txt は以下のとおりです。

format:brochure
clients: Goltsblat LTD
media: digital
genre: graphic design, illustration

ファイルシステムのレイアウトは以下のとおりです。

find catalog -name machine.txt
catalog/arch_brochure/machine.txt
catalog/bc_catalogue/machine.txt
catalog/bc_marching/machine.txt
catalog/cat_poster/machine.txt
catalog/doubledecker/machine.txt
catalog/hmco/machine.txt
catalog/mos_annual/machine.txt
catalog/mos_cd/machine.txt
catalog/mos_holiday2003/machine.txt
catalog/mos_mediaday2001/machine.txt
catalog/mos_mediaday2004/machine.txt
catalog/rg_booklets/machine.txt
catalog/risd_poster/machine.txt
catalog/risd_poster2/machine.txt
catalog/risd_poster3/machine.txt
catalog/sartcouncil_poster/machine.txt
catalog/tuscan_cover/machine.txt
catalog/wisdom_spirit/machine.txt
catalog/ymaa_kendo/machine.txt

また、values.awk は以下のとおりです。

# Limits matches to those under the parameter
# fieldname
# if this parameter is passed in from the command line

BEGIN{
    FS=":";
}

$1 ~ fieldname {

    #splits values at commas and dumps spaces
    split($2,values," *, *");

    # trims whitespace
    # replaces spaces with underscores
    # keeps count of unique values
    for(idx in values){
        valuename = values[idx];
        gsub(/^[ ]+|[ ]+$/,"", valuename);
        gsub(/ /,"_", valuename);
        valuecount[valuename]++;
    }

}

END {
    # outputs unique values and counts
    for(valuename in valuecount){
        print valuename,  "[" valuecount[valuename] "]";
    }
}

http://groups.google.co.jp/group/comp.lang.awk/browse_thread/thread/056c3727b10d6975/b20d7a68b0679913?hl=ja#b20d7a68b0679913


  • まず、 - Ed Morton (2006年01月11日 00時31分41秒)
sort | uniq

sort -u

と同じです。

で、次に、ファイルにコントロール文字が入っていないかどうかを cat -v で確認してください。

  • MS-DOS の ^M が入っていました。解決です。 - Lurker (2006年01月11日 00時33分20秒)

{{comment}}

[ 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 ]


最終更新時間:2007年07月30日 22時13分35秒