コミュニティ/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

お名前
件名
本文

(more quoting hell) - Mitch Urquhart (2006年01月06日 20時11分35秒)

WindowsXP で以下のように実行しましたが、うまくいきません。

UNIX 環境ではどうさしたのですが…。

awk95  'printf \" $pstr \\n\" , ((\$1 * 0.0111 * 2.0 ) + $.5 )'
infile.txt    >     outfile.txt

サンプルデータは以下のとおりです。

0
0
0
0
1
1
1
1
1
1
1
1
1
2
5
8
10
12
15
19
22
23
23
23
24
23

http://groups.google.co.jp/group/comp.lang.awk/browse_thread/thread/212dc59edbd08207/70fb43e4245624f6?hl=ja#70fb43e4245624f6


  • 間違っていました。 - Mitch Urquhart (2006年01月06日 20時12分41秒)
awk95  'printf \" $pstr \\n\" , ((\$1 * 0.0111 * 2.0 ) + $.5 )'   infile.txt
 > outfile.txt     #/ 間違い  <<<<<<<<
awk95  'printf \" $pstr \\n\" , ((\$1 * 0.0111 * 2.0 ) + 0.5 )'   infile.txt
 > outfile.txt    #/  正解   <<<<<<<<<<<<
  • 普通に回答すれば、いったんファイルにしてから実行させてみてください。 - Juergen Kahrs (2006年01月06日 20時15分55秒)
  • Cygwin を入れて、gawk を実行するのが近道だと思われます。 - Ed Morton (2006年01月06日 20時16分54秒)
  • 以下のようにしてみてください。 - Ted Davis (2006年01月06日 20時17分40秒)
awk "{printf(\"%.4f\n\", ($1 * 0.0222))}" infile.txt  >  outfile.txt

最後の +$.5 は無意味です。

{{comment}}

The name of script itself - MArek Simon (2006年01月04日 00時44分57秒)

実行させたスクリプトの名前を処理結果に埋め込みたいと考えています。

ARGV[0] では awk で ARGV[1] では処理ファイルになって、自分のスクリプトファイルの名前が得られません。

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


  • 一般的な方法としては awk 単体ではありません。 - Kenny McCormack? (2006年01月04日 00時45分41秒)
  • Fedora などの Linux であれば以下のようにできます。 - Kenny McCormack? (2006年01月04日 00時46分18秒)
BEGIN { getline t < "/proc/self/cmdline";split(t,T,"\0")
print "My name is:",T[3] }
  • 一般的な方法としては以下のようにするしかないでしょう。 - Janis Papanagnou (2006年01月04日 00時47分52秒)
awk -v scriptname=script.awk -f script.awk dataXX

また、複数の場合には以下のようにします。

  for awkprog in script_1.awk script_2.awk ... script_N.awk
  do
      awk -v scriptname="$awkprog" -f "$awkprog" dataXX
  done
  • ps を使って以下のようにできます。 - Ed Morton (2006年01月04日 01時01分02秒)
BEGIN{ while ("ps" | getline cmd > 0) print cmd }
  • history から探すこともできます。 - Alan Linton (2006年01月04日 22時00分46秒)
$ cat q.awk
NR==FNR {script=$6}
NR!=FNR && FNR==1 {print script}
#etc
$

$ history | gawk -f q.awk - q.dat
q.awk
$

$ history | tail -3
 1064  cat q.awk
 1065  history | gawk -f q.awk - q.dat
 1066  history | tail -3
$

この 6 番目の引数です。

" 1065  history | gawk -f q.awk - q.dat"
  • このようにして得ることができました。 - MArek Simon (2006年01月06日 19時58分32秒)
function name_of_script(     t,a)
{
         getline t <"/proc/self/cmdline"
         split(t,a,"\0")
         for (each in a)
                 if (a[each]=="-f") return a[each+1]
}

BEGIN{
         print name_of_script()
}
  • 配列の in は整列されないので、以下のようにしてみました。 - Ed Morton (2006年01月06日 20時01分07秒)
function name_of_script(     t,a,c)
{
         getline t <"/proc/self/cmdline"
         c = split(t,a,"\0")
         for (each=1; each<=c; each++)
                 if (a[each]=="-f") return a[each+1]
}

それでも、

gawk -ffile

よりも

gawk -f file

を使ってください。

  • 以下のような場合にはどうすればいいでしょうか? - MArek Simon (2006年01月06日 20時04分53秒)
awk -f lib.awk -f scriptXX.awk
  • 自分で特定しない限り、特定する方法はありません。 - Kenny McCormack? (2006年01月06日 20時05分59秒)
  • 以下のように変更してみました。 - Marek Simon (2006年01月06日 20時07分37秒)
function name_of_script(     t,a)
{
         getline t <"/proc/self/cmdline"
         split(t,a,"\0")
         for (each in a)
         {
                 if (a[each]=="-f") return a[each+1]
                 if (substr(a[each],1,2)=="-f") return substr(a[each],3)
         }
}
BEGIN{
         print name_of_script()
}
  • 以下のする方法もあります。 - Harlan Grove (2006年01月21日 19時56分36秒)
$ cat a.awk
{ SCRIPTID = "a.awk" }
NR % 2 == 1 { print SCRIPTID, NR, $0 }
$ cat b.awk
{ SCRIPTID = "b.awk" }
NR % 2 == 0 { print SCRIPTID, $0, NR }
$ echo 'a
b
c
d
e
f' | gawk -f a.awk -f b.awk
a.awk 1 a
b.awk b 2
a.awk 3 c
b.awk d 4
a.awk 5 e
b.awk f 6
$
  • 要約します。 - Marek Simon (2006年01月25日 00時14分40秒)
  1. どうしてもコマンドラインから自分のスクリプト名が知りたい
  2. OS 依存で /proc/self/cmdline から取得できるが、これは Linux のみ

また、これは大学で学生から聞かれた質問です。{{comment}}

awk arrays - Evie (2006年01月04日 00時38分30秒)

2 つの 100,000 エレメントの配列を使うのと、1 つの 2 次元配列を 100,000 個使うのとどちらが効果的ですか?

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


  • awk の配列は 1 次元配列でしかありませんので、どのくらい効果があるかは分かりません。 - Janis Papanagnou (2006年01月04日 00時40分30秒)

でも 2 次元配列の方が高速ではないでしょうか?{{comment}}

unix script won't run on Win32 - Mitch Urquhart (2006年01月04日 00時32分54秒)

WindowsXP で UNIX のツールを動作させようとしていますが、以下のものが動作しません。

awk95.exe '{printf "%1.0f \n" , ($1)}' corrected_4.1.txt  >
corrected_5.1.txt    &

入力ファイルは以下のとおりです。

-33.5
-32.5
-31.5
-30.5
-28.5
-26.0
-24.5
-23.0
-21.5
-20.5
-17.5
-14.5
-13.0
-11.5
-10.5
-9.5
-8.0
-6.5
-4.5
-2.5
-1.5
-0.5
1.0
2.5
3.0
2.5

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


  • Windows ではダブルクォートになるのでは? - Ed Morton (2006年01月04日 00時33分26秒)
  • 以下のようにしてみてください。 - Ted Davis (2006年01月04日 00時34分03秒)
awk95.exe "{printf \"%1.0f \n\" , ($1)}" corrected_4.1.txt  >
corrected_5.1.txt

また、最後の & は無視されます。

{{comment}}

Regex substitution doesn't work in begin??? - Myself (2006年01月04日 00時25分57秒)

echo theaboveline | gawk -F, '
BEGIN
{
    gsub(/\([^\)]*\)/,"",$0)
};
{
    for (i=1;i<=NF;i++)
    {
        printf $i
    }
    print "\n"
}'

というのは動作しませんが、

echo theaboveline | gawk -F, '
{
    for(i=1;i<=NF;i++)
    {
        gsub(/\([^\)]*\)/,"",$i);
    }
    print;
}'

というのは動作します。

BEGIN で gsub が動作しないのはどうしてでしょうか?

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


  • 以下のようにすれば分かりますよ。 - Doug McClure? (2006年01月04日 00時26分59秒)
BEGIN
{
              print $0
    gsub(/\([^\)]*\)/,"",$0)
};
  • つまり、gsub() が悪いのではなく、$0 がセットされていないのです。 - Ed Morton (2006年01月04日 00時27分55秒)

{{comment}}

NEWBIE: how to find and kill by Parent PID - Atropo (2006年01月04日 00時19分02秒)

5:00 にメンテナンス目的でシャットダウンします。

その際に新しいプロセスが起動した時にコンフリクトするので、古いプロセスの親プロセスを kill します。

$ ps -fea|grep "process"|grep -v grep|awk '{$3 == "\ 1"}
{print $2,$3}'

のようにしようとしていますが、

75555 1  --> the new one
96666 1  --> the old one.

の両方が得られます。うまく選択できますか?

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


  • これは shell の質問ですよ。 - Ed Morton (2006年01月04日 00時19分56秒)
  • awk はこうしたことに適しているわけではありませんが、以下を試してみてください。 - Michael Hughes (2006年01月04日 00時20分35秒)
       # PROCESS=init
       # SIGNAL=SIGSEGV
       # ps h --ppid `pidof $PROCESS` -o pid |                            \
       if which xargs >/dev/null 2>1;                                     \
               then                                                       \
                       xargs kill -s $SIGNAL;                             \
               else                                                       \
                       awk \{print\ \"kill\ -s\ $SIGNAL\ \"\ \$1\} | sh;  \
       fi

また、以下を参照してください。

{{comment}}

multi-dimensional arrays - confuzzled (2005年12月28日 01時28分08秒)

以下のようなフォーマットを持ったマルチブロックのファイルがあります。

Name: blah blah
Address: street address
city,state,zip
Date: blah/blah/blah
License Status: blah blah
etc.

最低で 7 行のブロックになっています。

これを "first,last", "address", "date" のように並べて記憶しておきたいのですが、多次元配列がよさそうであると考えました。

j=0; done=0;
while (!done)
{
(1) n=split($0, array[j], ":");
printf("%s", array[j,n]);
j++;
next;
if ($0 == "") done=1;
}

http://groups.google.co.jp/group/comp.lang.awk/browse_thread/thread/003d107b693ba900/0cd86bd097351e12?hl=ja#0cd86bd097351e12


  • awk では以下のようにします。 - William James (2005年12月28日 01時28分24秒)
RS = ""

また、もしも空行ではなく、スペースかタブのようなものを含んでいる場合には以下のようにします。

RS = "\n([ \t]*\n)+"

そこで、以下のようにします。

BEGIN {
  # The record-separator will be an empty line.
  RS = ""
  # The field-separator will be a newline.
  FS = "\n"
}

/\nLicense Status: +expired/ {
  sep = ""
  for (i=1; i<= NF; i++)
  { n = split( $i, array, ": +" )
    printf "%s\"%s\"", sep, array[ n ]
    sep = ", "
  }
  print ""
}
  • 以下を試してみてください。 - Ed Morton (2005年12月28日 01時30分45秒)
$ awk -v RS= '/(^|\n)License Status: blah blah\n/ &&
gsub(/\n[^:]*:/,"\n") && sub(/^[^:]*: /,"")' file

または gawk であれば、以下のようにします。

$ awk -v RS= '/(^|\n)License Status: blah blah\n/{print
gensub(/(^|\n)[^:]*: /,"\\1","g")}' file
  • 間違えていました。 - Ed Morton (2005年12月28日 01時32分55秒)
$ awk -v RS= '/(^|\n)License Status: blah blah(\n|$)/ && gsub(/\n[^:]*:
/,"\n") && sub(/^[^:]*: /,"")' file

または gawk であれば、以下のようにします。

$ awk -v RS= '/(^|\n)License Status: blah blah(\n|$)/{print
gensub(/(^|\n)[^:]*: /,"\\1","g")}' file

オリジナルポストの要望どおりにするのであれば、以下のようにします。

$ awk -v RS= '/(^|\n)License Status: blah blah(\n|$)/{gsub(/\n[^:]*:
/,"\",\"");sub(/^[^:]*: /,"\"");$0=$0"\"";print}' file

{{comment}}

TAWK 5.0 - tallem (2005年12月25日 02時08分15秒)

tawk 4.1a を使っていましたが、非常にスピードが遅くメモリも多く消費していました。そこで、これらの改善をしましたが、tawk は 5 になっていました。

簡単にバージョンアップする方法はありますか?

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


  • tawk 4 は 16 bit DOS Extender を用い、tawk 5 は 32 bit DOS Extender を用いています。 - Anton Treuenfels (2005年12月29日 23時41分42秒)

ですから、

BEGIN {

    local i
    local test

    for ( i = 1; i < 1000000; i++ ) {
        test[ "NDX1" ] = ".T."
        test[ "NDX2" ] = ".F."
        if ( !(i/1000) )
                print i
    }
}

のようなプログラムで差が現れ、tawk 4 でエラーになります。

  • tawk V5c for Windows では巨大な配列を使用する際にディスクを使用しますので、巨大な配列でも扱うことができます。 - trexx (2006年01月11日 00時24分23秒)
BEGIN {

    local i
    local test
    starting_time = time()
    for ( i = 1; i < 100000000; i++ ) {
        test[ i ] = "time in seconds " time()-starting_time
        if ( !(i%100000) ) {print "test["i"]="test[i] }
    }
}
c:\u\awk>awkw -f test.awk
test[100000]=time in seconds 1
test[200000]=time in seconds 2
test[300000]=time in seconds 3
test[400000]=time in seconds 4
test[500000]=time in seconds 5
test[600000]=time in seconds 6
...
test[5100000]=time in seconds 421
test[5200000]=time in seconds 436
test[5300000]=time in seconds 449
test[5400000]=time in seconds 463
test[5500000]=time in seconds 479
test[5600000]=time in seconds 488
test[5700000]=time in seconds 541
test[5800000]=time in seconds 597
awk: program aborted by SIGINT signal
c:\u\awk>

{{comment}}

OSA and awk (Mac) - Robert Peirce (2005年12月23日 01時14分07秒)

AppleScript? に置き換わるような言語を探しています。思い浮かんだのは java と python ですが、勉強している時間もありません。そこで、awk を思い出しました。

AppleScript? に置き換わるような awk のバージョンを知りませんか?

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


  • 以下のようにして実行できるのではないでしょうか? - Bob Harris (2005年12月23日 01時14分53秒)
   system("osascript ........")

   cmd = "osascript ......"
   cmd | while getline {
       ...
   }
   close(cmd)
  • JAVA ではなく、javascript では? - Steve Hix (2005年12月24日 00時13分57秒)

{{comment}}

Problem creating csv file - Luis (2005年12月23日 01時05分08秒)

以下のようにコマンドを実行しています。

gawk.exe -f Fund.awk Input.txt >> Output.txt

ここで、Fund.awk は以下のようなものです。

/Global Fund of Funds/{printf ("FEGL,")}
/Price data as at/{printf substr($0, 34, 4) "/"} # Year
/Price data as at/{printf substr($0, 30, 3) "/"} # Month
/Price data as at/{printf substr($0, 27, 2) ","} # Day
/NAV Price/{printf substr ($0, 24, 6)}

また、Input.txt は以下のようになっています。

     Global Fund of Funds
     Price data as at:       15-Dec-2005
     NAV Price (c):      208.10 c

結果は以下のようになります。

FEGL,2005/Dec/15,208.10
FEGL,208.10,2005/Dec/15

という結果が欲しいので、以下のように実行しました。

/Global Fund of Funds/{printf ("FEGL,")}
/NAV Price/{printf substr ($0, 24, 6)}
/Price data as at/{printf substr($0, 34, 4) "/"} # Year
/Price data as at/{printf substr($0, 30, 3) "/"} # Month
/Price data as at/{printf substr($0, 27, 2) ","} # Day

でも、結果は同じで、

FEGL,2005/Dec/15,208.10

となります。

http://groups.google.co.jp/group/comp.lang.awk/browse_thread/thread/128bdfcd6efbeaa0/7a2fdacf8a1100d8?hl=ja#7a2fdacf8a1100d8


  • 以下の部分を加えてみてください。 - Juergen Kahrs (2005年12月23日 01時06分10秒)
/Price data as at/ { split($NF, d, "-") }
/NAV Price/{ printf("FEGL,%s,%s/%s/%s\n", $(NF-1), d[3], d[2],d[1] ) }

SuSE Linux では問題なく動作しています。

gawk -f Fund.awk Input.txt
FEGL,208.10,2005/Dec/15

MS-DOS マシンでは、改行が異なるかもしれません。

また、

は参考になるでしょう。

  • 別の解として以下のようなものがあります。 - Ed Morton (2005年12月23日 01時09分15秒)
BEGIN{OFS=","; RS="Global.*Funds"}
NF{$5=gensub(/(.*)-(.*)-(.*)/,"\\3/\\2/\\1","",$5); print "FEGL",$9,$5}
  • WindowsXP と Red Hat Linux でうまく動作しました。 - Luis (2005年12月23日 01時10分35秒)

{{comment}}

new xgawk time functions (sleep and gettimeofday) - Andrew Schorr (2005年12月21日 01時07分48秒)

http://sourceforge.net/projects/xmlgawk で開発しているものに新しい関数が加わりました。

$ cat testtime.awk
@load time

BEGIN {
   delta = 2.347
   printf "Start time = %.6f [systime = %s]\n",t0 = gettimeofday(),
systime()
   printf "Sleep(%s) return code = %s\n",delta,sleep(delta)
   printf "End time = %.6f [systime = %s]\n",t1 = gettimeofday(),
systime()
   printf "Elapsed time = %.6f\n",t1-t0
}

$ xgawk -f testtime.awk
Start time = 1135090599.902198 [systime = 1135090599]
Sleep(2.347) return code = 0
End time = 1135090602.251463 [systime = 1135090602]
Elapsed time = 2.349265

ただし、Windows での実装は試していません。動作が分かったら、フィードバックして欲しいです。

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


{{comment}}

Append to previous line if line ends with - - burkina (2005年12月21日 01時01分28秒)

以下のようなファイルがあり、- で終わっているときには行を追加したいと考えています。

259.765533 259.765533 259.765533 259.766022 259.770325 259.756989
259.649628-
  259.608032 259.571381 259.578644 259.646057 259.814117 259.958008
260.084534-
  260.329102 260.453522 260.766083 261.103699 261.405121 261.690399
261.935974-
  261.983154 262.097229 325.628143 324.821747 324.412079 324.479218
324.092316-
  322.912964 322.120209 320.396545 319.260681 319.515808 321.214417
323.874481-
  264.634735 264.785217 338.487793 338.489655 338.383942 338.384003
338.384003-
  338.383942 375.625 382.076263 343.581024 339.971375 339.534119
339.204193-
  338.383911 338.383911
259.501312 259.501312 259.501312 259.515961 259.527374 259.475983
259.274963-
  259.243774 259.210724 259.235321 259.394989 259.680603 259.626099
259.790222-
  260.003021 260.265015 261.702576 261.696655 261.174072 261.4245
261.619385-
  261.669067 261.690369 261.654694 323.6828 323.701202 324.009613
324.108429-
  323.40387 322.146271 320.545746 319.301636 318.636719 318.400696
323.124878-
  324.112885 264.21524 338.507812 338.505463 338.384033 338.384155
338.384125-
  338.384125 377.991394 362.469666 358.296997 344.468903 341.669128
346.023102-
  338.383911 338.383911

行末の "-\n" をスペースに置換するにはどうすればいいでしょうか?

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


  • gawk なら、以下のようにします。 - Ed Morton (2005年12月21日 01時01分55秒)
awk -v RS="-\n" -v ORS=" " '1'
  • スペースはそのままにしておきたいのです。 - burkina (2005年12月21日 01時03分33秒)
  • 以下のようにします。 - Ed Morton (2005年12月21日 01時03分45秒)
awk -v RS="-\n  " -v ORS=" " '1'

または

awk -v RS="-\n " -v ORS= '1'

とします。

最短のスクリプトなら以下のようにします。

awk 1 RS="-\n " ORS= file

{{comment}}

GAWK oddity... - Kenny McCormack? (2005年12月21日 00時48分53秒)

#!/usr/bin/gawk -f
BEGIN   {
    $0 = "    12\n     34\n   97\n"
    RS = "";FS=/[ \n]+/;OFS="|"     # This line!
    $1=$1
    print
    }

というものがあります。ここで期待されるものは以下のとおりです。

12|34|97

でも、結果は

    12|     34|   97|

となります。http://groups.google.co.jp/group/comp.lang.awk/browse_thread/thread/7fba031de4e79303/96d860ecef05b5f6?hl=ja#96d860ecef05b5f6


  • FS が間違っています。 - Don Stokes (2005年12月21日 00時49分49秒)
FS=/[ \n]+/

が違っています。やりたいことは、

#!/usr/bin/gawk -f
BEGIN  {
    FS = "[ \n]+"           # Define the field separation
    $0 = "    12\n     34\n   97\n" # Assign the record
    OFS = "|"           # Set OFS for output
    $1 = $1             # Re-format $0 using the new OFS
    print               # Output the line
}

ということではないでしょうか?

  • つまり、以下のようなことです。 - Don Stokes (2005年12月21日 00時52分43秒)
FS=" "  ; $0 = " a b "     -> NF=2, $1="a", $2="b"
FS=" +" ; $0 = " a b "     -> NF=4, $1="",  $2="a", $3="b", $4=""
  • ヘルプが欲しいのではなく、これが理にかなっているか? ということを皆に聞きたいんです。 - Kenny McCormack? (2005年12月21日 00時54分32秒)

特に、gawk と tawk の挙動が異なるのがこの正規表現の部分で、

   /foo/ {print "Foo!"}        # still works as expected.

は大丈夫だけど、

   r = /foo/ { print "r =",r }     # 4

   function f(x) { print "typeof(x) =",typeof(x);return x }    # regular_expression
   r = f(/foo/) { print "r =",r }  # foo

は不明確な部分です。

  • tawk と gawk の正規表現の扱いは異なり、そういうものです。 - Harlan Grove (2005年12月23日 00時59分30秒)

{{comment}}

awk variables not passing to redirection issue - Jay C. James (2005年12月18日 00時38分25秒)

以下のような変数を読み込むような awk スクリプトを動作させたいのですが、うまく動作しません。

#!/bin/ksh

LogID=jay
GroupID=112344
Pid=$$

echo | awk -varLOGID=$LogID -varGROUPID=$GroupID -varPID=$Pid '{
printf("%-8s -- %+6.4s\n", LogID,GroupID) >> $Pid.views.emailfile
}'

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


  • 以下の点に注意してみましょう。 - Ed Morton (2005年12月18日 00時39分25秒)
  1. awk は -var ではなく、-v です。このままでは arLOGID という変数を読み込みます。
  2. -v の次にはスペースが必要です。
  3. echo ではなく、BEGIN でできるのでは?
  4. awk の変数には $ は必要ありません。
  5. .views.emailfile を Pid 変数の後に付けるんですよね。
  6. printf には括弧は必要ではありません。
  7. >> がどういう意味か知っていますか?

そして以下を試してみてください。

awk -v LogID="$LogID" -v GroupID="$GroupID" -v Pid="$Pid" 'BEGIN{
printf "%-8s -- %+6.4s\n",LogID,GroupID >> Pid ".views.emailfile"
}'

{{comment}}

searching for control chars - cumin (2005年12月18日 00時26分45秒)

Windows2000 上の gawk 3.1.4 で CTRL-Z を探そうと思い以下のようにしました。

Q:\>gawk "/[:cntrl:]/ file >file2

最後に 0x1a (^z) があります。

0000000: 4330 3234 3233 3233 7c52 5553 7c53 7c4c  C0242323|RUS|S|L
0000010: 3534 3833 3730 347c 5046 7c53 3632 3638  5483704|PF|S6268
0000020: 3736 307c 597c 4138 3035 3434 3630 7c7c  760|Y|A8054460||
0000030: 4d30 3031 3034 3438 7c44 3034 3937 3131  M0010448|D049711
0000040: 7c4d 5348 5255 537c 5359 7c44 3034 3937  |MSHRUS|SY|D0497
0000050: 3131 7cd0 a1d0 9ed0 92d0 a0d0 95d0 9cd0  11|.............
0000060: 95d0 9dd0 9dd0 90d0 af20 d098 d0a1 d0a2  ......... ......
0000070: d09e d0a0 d098 d0af 20d0 9cd0 95d0 94d0  ........ .......
0000080: 98d0 a6d0 98d0 9dd0 ab1a 7c33 7c4e 7c7c  ..........|3|N||
0000090: 0a

他の CR, LF, NL などを見つける手段はありますか?

http://groups.google.co.jp/group/comp.lang.awk/browse_thread/thread/5130df5975838ffd/3eb79ae24b65481f?hl=ja#3eb79ae24b65481f


  • ^Z で止まるのは、awk の問題ではなく、Windows のファイル形式の問題です。 - Roberto Waltman (2005年12月18日 00時27分48秒)
  • Cygwin を入れれば、*IX と同じになりますので、以下のようにして ^Z を探すことができます。 - Ted Davis (2005年12月18日 00時29分16秒)
gawk '{if($0 ~ /\x1a/) print $0}' /tmp/foo.txt
  • GNU od があれば、可能です。 - Eric Pement (2005年12月18日 00時30分38秒)
od -An -tx1 -a file | gawk -f fix_od.awk

とします。fix_od.awk は以下のとおりです。

 # filename: fix_od.awk
 #  purpose: massage the output of od -An -tx1 -a
 #     We will want to display exact control codes (0x00-0x1f)
 #     unless the control code is LF (0x0a) or CR (0x0d).
 #     All other lines will not be printed.

 function print3lines(line) {
    gsub(" ", "  ",line)
    getline a
    b = toupper(line) "\n" a "\n"
    print b
    counter++
 }

 /^\*$/ {
    # Lines that begin with a single '*' indicate that od has
    # encountered a duplicate run of 16 bytes from the line above.
    if ( b ~ /0[0-9bcef]/ ) {
       print b
       counter++
    } else if ( b ~ /1[0-9a-f]/ ) {
       print b
       counter++
    }
    next
 }

 /0[0-9bcef]/ { print3lines($0); next }
 /1[0-9a-f]/  { print3lines($0); next }
 /0[ad]/      { getline; next         }

 END {
    if (counter)
       print counter " line(s) of control codes found.";
    else
       print "No control codes found.";
 }
 #---end---

すると以下のように出力されます。

C:\> od -An -tx1 -a foo | c:\djgpp\bin\gawk.exe -f fix_od.awk
  61  62  63  00  04  64  65  66  0D  0A  69  73  20  61  20  74
   a   b   c nul eot   d   e   f  cr  nl   i   s  sp   a  sp   t

1 line(s) of control codes found.

16 進数ダンプが欲しい場合には以下のようにします。

od -An -tx1 -a file | gawk -f hexdump.awk

として、

  # filename: hexdump.awk
  #  purpose: change the output of od -An -tx1 -a to hexdump
  /^\*$/ { print b; next }
  {
      gsub(" ", "  ")
      getline a
      b = toupper($0) "\n" a "\n"
      print b
  }
  #---end---

で実行させます。

  • Cygwin が非常に有効だと思います。 - Stephan Titard (2005年12月21日 00時46分28秒)

{{comment}}

asort'ing - Sebastian Luque (2005年12月14日 23時42分02秒)

Acta Endocrinologica    Acta Endocrinol Acta Endocrinol.
Acta Endocrinologica    Acta Endocrinol (Copenh)    Acta Endocrinol. (Copenh).

のような行があります。これを

@string { actaendocrinol = "Acta Endocrinologica" }

のようにして、ソートしたいのです。

#! /usr/bin/gawk -f

BEGIN {             # Setup variables and help with -h
    pn = "stringBib.awk"

    for (i = 1; i < ARGC && ARGV[i] != "-h"; i++){
    if (ARGV[i] ~ /fldsep/) FS = fldsep
    if (ARGV[i] ~ /patfld/) patfld = patfld
    if (ARGV[i] ~ /repfld/) repfld = repfld
    if (ARGV[i] ~ /^-pat/) {pat = 1; delete ARGV[i]}
    }

    if (i != ARGC) {usage(pn); exit}
    if (!fldsep) FS = OFS = fldsep = "\t"
    if (!patfld) patfld = 1
    if (!repfld) repfld = 3
}

{
    # standardize to lower case and remove punctuation for comparisons
    lcpat = gensub(/\W/, "", "g", tolower($patfld))
    lcrep = gensub(/\W/, "", "g", tolower($repfld))

    if (lcpat in arpat || lcrep in arrep) { # skip if we've seen the pattern
    printf "%s [%d]: repeated entry ignored\n",
        FILENAME, FNR > "/dev/stderr"
    next
    } else {            # otherwise, store both fields in arrep
    arpat[lcpat]++      # just a counter
    arrep[lcrep] = sprintf("%s\t%s", $patfld, $repfld)
    }
}

END {               # produce output based on populated array
    asort(arrep)                # not doing anything for now
    for (i in arrep) {
    split(arrep[i], tmp, "\t")
    str = genshnd(tmp[2])

        if (pat) {
            printf "@string { %s = \"%s\" }\n", str, tmp[1]
        } else {
            printf "@string { %s = \"%s\" }\n", str, tmp[2]
        }
    }
}


# Help message
function usage(pn) {
    printf "USAGE: %s [variables to initialize] file ...\n\n", pn
    printf "VARIABLES:\n%15s %s\n%15s %s\n%15s %s\n%15s %s\n\n",
    "-pat", "(Option) Whether to generate pattern string (Default: no)",
    "patfld =", "Field (integer) containing pattern to match (Default: 1)",
    "repfld =", "Field (integer) containing replacement string (Default: 3)",
    "fldsep =", "Field separator (string) for interpreting input (Default: \"\\t\")"
    print "DETAILS:\n    Generates lines of the form: \n\n\
    \'@string { shorthand = \"replacement\" }\'\n\n\
    \"shorthand\" is built by tranforming \"repfld\" to lower case, stripping all whitespace.\\
n\
    \"replacement\" is built with the intact \"repfld\".\n\n\
    Use the -pat option to generate the @string definition for the pattern,\n \
    rather than for the replacement."
}

# Generate the shorthand
function genshnd(s, i) {
    nwords = split(s, arr, /[[:blank:]]/)
    for (i in arr) {
    gsub(/\W/, "-", arr[i])
    gsub(/-+$/, "", arr[i]) # remove if it's at end of word
    }

    abbr = arr[1]

    if (nwords > 1) {
    for (i = 2; i <= nwords; i++)
        abbr = abbr arr[i]
    }

    return tolower(abbr)
}

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


  • asort() よりも asorti() の方がやりたいことをできるのではないでしょうか? - Ed Morton (2005年12月14日 23時43分33秒)
  • 以下のようにしてはダメですか? - Juergen Kahrs (2005年12月14日 23時44分11秒)
gawk -f myscript.awk | sort
  • 以下のようにすれば良かったようです。 - Sebastian Luque (2005年12月14日 23時45分25秒)
END {               # produce output based on populated array
    asort(arrep)                # not doing anything for now
    for (i in arrep) {
        ^^^^^^^^^^

END {               # produce output based on populated array
    n = asort(arrep)                # not doing anything for now
    for (i = 1; i <= n; i++) {

{{comment}}

Multi Line awk with RS set to equal sign - jason.berendsen (2005年12月14日 23時36分11秒)

Solaris の CPU に関するログの部分だけを抜き出したいと考えています。

========================= CPUs =========================

                    Run   Ecache   CPU    CPU
Brd  CPU   Module   MHz     MB    Impl.   Mask
---  ---  -------  -----  ------  ------  ----
SYS     0     0      296     2.0   US-II    2.0


========================= Memory =========================

何かアイデアはありますか?

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


  • 以下を試してみてください。 - Ed Morton (2005年12月14日 23時36分38秒)
prtdiag | awk '/=== CPUs ===/,/=== Memory ===/'
prtdiag | awk '/====/{f=0}f;/=== CPUs ===/{f=1}'
  • 問題なく動作しています! - jason.berendsen (2005年12月14日 23時37分32秒)
  • いくつかアイデアはあります。 - Loki Harfagr (2005年12月14日 23時38分08秒)
$ awk '/^=====.*$/{next}; 1 '
$ awk '/^=====.*CPUs/{next}; /^=====.*Memory/{exit}; 1 '

などです。

{{comment}}

gawk not seeing lines - cumin (2005年12月14日 23時21分11秒)

Windows2000 で gawk 3.1.3 を使っても、DJGPP で gawk 3.1.4 を使っても同じ結果だったのですが、

# RXCUI.awk
BEGIN {FS="\|"}$12 ~ /RXNORM/

3665 行がヒットしますが、grep では 295159 となります。

C1608308|ENG|S|L3595178|VO|S4242223|Y|A8112482|1355724|283865||RXNORM|OCD|RX10283865|FACTORIX HUMAN RECOMBINANT 250 (+/-)U KIT|0|O||
C1608309|ENG|S|L3595170|PF|S4281309|Y|A8151203|1474745|314966||RXNORM|OCD|RX10314966|ANTIHEMOPHILICFACTOR, HUM REC @ 250 (+/-)U @ KIT|0|O||

という行がヒットしているようです。

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


  • grep では $12 かどうかは判断できませんよ。 - Ed Morton (2005年12月14日 23時21分44秒)
cat -v file
cut -t\| -f12 file | grep RXNORM
awk 'BEGIN {FS="|"}/RXNORM/' file
awk 'BEGIN {FS="|"}/RXNORM/{for (i=1;i<=NF;i++) { if ($i ~ /RXNORM/)
print i, $i }}' file
osds2unix file

を試してみてください。

  • cut コマンドで調べてみました。 - cumin (2005年12月14日 23時24分24秒)
Q:\UMLS_AC\rrf>cut -d"|" -f12 MRCONSO.RRF | grep RXNORM > cutted
Q:\UMLS_AC\rrf>gawk -f rxcui.awk MRCONSO.RRF >cutted2
Q:\UMLS_AC\rrf>gawk 'BEGIN{FS="|"}/RXNORM/' MRCONSO.RRF > cutted3
  • まず、私のスクリプトを試してみてください。 - Ed Morton (2005年12月14日 23時25分24秒)
  • 私のところには osds2unix がないので、以下の部分を試しました。 - cumin (2005年12月14日 23時26分54秒)
#cutted.awk
BEGIN {FS="|"}
/RXNORM/ {
   for (i=1; i<=NF; i++) {
      if ($i ~ /RXNORM/)
         print i, $i
   }
}

全て "12 RXNORM" となっていて、3665 となっています。どうもここにコントロール文字があるのかもしれません。

  • ^M を除くために以下のようにしてみてください。 - Ed Morton (2005年12月14日 23時29分32秒)
gawk '{gsub(/^M/,"")}1' file > newfile
gawk '{gsub(/\r/,"")}1' file > newfile
  • それでもダメなようです。 - cumin (2005年12月14日 23時31分20秒)
  • ^Z が挿入されているのではないでしょうか? - Ted Davis (2005年12月14日 23時32分04秒)
  • ^Z はないようです。 - cumin (2005年12月14日 23時32分45秒)
Q:\UMLS_AC\rrf>sed -n "/\x1a/p" MRCONSO.RRF
  • データを Web サイトに置けますか? - Kenny McCormack? (2005年12月14日 23時33分27秒)
  • ファイルが 700 MB あるので置けません。 - cumin (2005年12月14日 23時33分55秒)
  • 職場の人が ^Z がファイルに含まれているのに気がついてくれました。 - cumin (2005年12月16日 00時19分23秒)
  • dos2unix で行末の変換はできます。 - Dave Thompson (2005年12月21日 00時45分27秒)

{{comment}}

Pulling out fields in a CSV file - usenet (2005年12月14日 01時46分40秒)

CSV ファイルから shell の変数へ格納することはできますか?

http://groups.google.co.jp/group/comp.lang.awk/browse_thread/thread/fbe4ebf5c0249d4f/63adf279e334f286?hl=ja#63adf279e334f286


  • 以下を試してみてください。 - karthicksmail (2005年12月14日 01時47分16秒)
#!/bin/bash

NUMREC=`awk ' END { print NR } ' file.txt`
for i in `seq 1 $NUMREC`
do
        FIELD1=`head -$i file.txt | tail -1 | awk ' { print $1 } '`
        echo $FIELD1
done

こういった感じでいいのでしょうか?

  • 以下のようにしてみました。 - usenet (2005年12月14日 23時14分34秒)
#!/bin/bash

NUMREC=`awk ' END { print NR } ' watc.ed`

for i in `seq 1 $NUMREC`;
 do
  HOSTNAME=`head -n $i watc.ed | tail -n 1 | awk -F "," ' { print $1 }
'`;
  IP=`head -n $i watc.ed | tail -n 1 | awk -F "," ' { print $2 } '`;
  MODEL=`head -n $i watc.ed | tail -n 1 | awk -F "," ' { print $3 } '`;

  SITE=`head -n $i watc.ed | tail -n 1 | awk -F "," ' { print $5 } '`;
  BUILDING=`head -n $i watc.ed | tail -n 1 | awk -F "," ' { print $6 }
'`;
  ROOM=`head -n $i watc.ed | tail -n 1 | awk -F "," ' { print $7 } '`;
  hostname=$(echo $HOSTNAME | tr A-Z a-z)
  cat network-template.cfg | sed -e "s/HOSTNAME/$hostname/g" \
  -e "s/MODEL/$MODEL/g" \
  -e "s/LOCATION/$SITE $BUILDING, $ROOM/g" \
  -e "s/IP/$IP/g" > $hostname.watc.local.cfg && echo "Wrote
$hostname.watc.local.cfg";
done

CSV とは一致して、うまく動作しているようです。

  • CSV が簡単なのであれば、以下のようなこともできます。 - William Park (2005年12月21日 00時42分23秒)
   IFS=,
   x='11,22,33'

   set -- $x; echo $1
   read a b c <<< "$x"; echo $a

でも、複雑な場合は CSV 拡張を使うのが賢明でしょう。

つまり、

   IFS=$' \t\n'
   x='"1,1",22,33'

   read -C a b c <<< "$x"; echo $a
   set -- "${x|,}"; echo $1

のようにします。

  • head や tail を使う必要はないです。 - Dave Thompson (2005年12月26日 22時29分26秒)

HOSTNAME = ` awk -F, -vi=$i 'NR==i {print $1;exit}' watc.ed `

または

HOSTNAME = ` awk <watc.ed -F, -vi=$i 'NR==i {print $1;exit}' `

とします。また、多くの shell では複数の変数が扱えるので、

for i in `seq blah`; do
awk <watc.ed -F, -vi=$i 'NR==i {$1=$1;print;exit}' >temp
<temp read HOSTNAME IP MODEL NOTUSED SITE BUILDING ROOM
# edit and write file for this item
done

のようにできます。単純な CSV であれば、

for i in `seq blah`; do
awk <watc.ed -vi=$i 'NR==i {print;exit}' >temp
<temp IFS=, read HOSTNAME IP MODEL NOTUSED SITE BUILDING ROOM
# edit and write file for this item
done

のようにできます。また、awk を使って以下のようにもできます。

awk -F, 'NR==FNR {template = template $0 RS;next}
 {copy=template; gsub(/IP/, $2, copy); etc etc
 print copy > "perhost." $1 }' template watc.ed

{{comment}}

"getline inside END" issue - xie bo (2005年12月14日 01時41分35秒)

Solaris 10 では以下のようになります。

$ cat sr7922.awk
        {
        }
END {
        getline
        }
$ cat sr7922.tdf
ccccccccccccccccccccccccc
$ /usr/xpg4/bin/awk -f sr7922.awk sr7922.tdf
$ echo $?
0

AIX 5.3 では以下のようになります。

$ awk -f sr7922.awk sr7922.tdf
$ echo $?
0

nawk では END での getline は既に読み込む行がないので、エラーになって 1 を返すのではないかと思います。どうなのでしょうか?

http://groups.google.co.jp/group/comp.lang.awk/browse_thread/thread/accc981f9f389f94/00b4dbb40b5e716d?hl=ja#00b4dbb40b5e716d


  • exit しても END の getline は動作します。 - Ed Morton (2005年12月14日 01時42分38秒)
$ echo "abc" | awk 'BEGIN{exit}END{getline;print $0}'
abc

つまり、エラーでも無視でもなく、処理しているわけです。

  • man page を読む限り 0 を返すので良いと思います。 - gerryt (2005年12月14日 01時44分36秒)
  • いったい man page のどこに 0 を返すと書いているのか、どこに END での getline についての言及があるのかを示してください。 - xie bo (2005年12月14日 23時11分43秒)
  • それを知ってどうするんですか? END だからといって getline が異なった動作をするとは書かれていませんよ。 - Chris F.A. Johns (2005年12月14日 23時13分22秒)

{{comment}}

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


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