AWK:列が始まる場所をどのように知ることができますか?

AWK:列が始まる場所をどのように知ることができますか?

入力行を解析した後、awkは元の行($0)と各個々の列($1、、、$2...)へのアクセスを提供します。このプロセスを実行している間(要求が遅くなります)、2番目の列の文字位置が始まる場所を正確に知っています。

  1. この情報へのアクセスを提供しますか(たとえば、元の行$ 0から2番目の列が始まる場所)。
  2. そうでなければ正しく見つけるための健全でエレガントな方法はありますか? (動的正規表現の使用FS、特殊なケースの処理、キャプチャグループの使用などを介してawkの内部動作をエミュレートする醜くて非効率的な方法を作成しようとしていますが、詳細についてはFS==" "アドバイスが必要です。)

例1(デフォルトFS):

$ echo -n -e " \tFirst \t\t  Second \t Third  \t"\
|awk -F" " '{print "FS:["FS"]";for(i=0;i<=5;i++)if(""!=$i)print "$"i":["$i"]"}'\
|sed 's/\t/\\t/g'

FS:[ ]
$0:[ \tFirst \t\t  Second \t Third  \t]
$1:[First]
$2:[Second]
$3:[Third]

Secondここ - 2番目の列()が文字で始まることに注意してくださいS13番入力行の文字(したがってFirstキーとして保存し、Second \t Third \t後で使用するために値全体を値に保持/保存できます)


例2(TABをFSとして使用):

$ echo -n -e " \tFirst \t\t  Second \t Third  \t"\
|awk -F"\t" '{print "FS:["FS"]";for(i=0;i<=5;i++)if(""!=$i)print "$"i":["$i"]"}'\
|sed 's/\t/\\t/g'

FS:[\t]
$0:[ \tFirst \t\t  Second \t Third  \t]
$1:[ ]
$2:[First ]
$4:[  Second ]
$5:[ Third  ]

Firstここ - 2番目の列()が文字で始まることに注意してくださいF3番目の場所入力行の文字 - (スペース)をキーとして保存し、First \t\t Second \t Third \t後で使用するために値としてそのまま保持/保存できます。


例3(カスタマイズされたFS):

$ echo -n -e " \tFirst \t\t  Second \t Third  \t"\
|awk -F"[ \t]+" '{print "FS:["FS"]";for(i=0;i<=5;i++)if(""!=$i)print "$"i":["$i"]"}'\
|sed 's/\t/\\t/g'

FS:[[ \t]+]
$0:[ \tFirst \t\t  Second \t Third  \t]
$2:[First]
$3:[Second]
$4:[Third]

Firstここ - 2番目の列()が文字で始まることに注意してくださいF3番目の場所行に文字を入力します。これにより、最初の列が空の文字列であることがわかり、後でFirst \t\t Second \t Third \t使用できるように値として保存されます。


例4(複合FS):

$ echo "-11...22;,;..;33-44...;"\
|awk -F"[^0-9-]+" '{print "FS:["FS"]";for(i=0;i<=5;i++)if(""!=$i)print "$"i":["$i"]"}'

FS:[[^0-9-]+]
$0:[-11...22;,;..;33-44...;]
$1:[-11]
$2:[22]
$3:[33-44]

22ここ - 2番目の列()が文字で始まることに注意してください27番行に文字を入力してください。これにより、後で使用できるように-11キーと値で保存できます。22;,;..;33-44...;


デフォルトでは、アイデアはカスタム使用のためにいくつかの(最初の)列を取得し、行の残りの部分(2番目の列から行の終わりまで)をそのまま保持(変数に保存)することです。

ベストアンサー1

Split() の 4 番目の引数として GNU awk を使用します。

$ cat tst.awk
{
    split($0,flds,FS,seps)
    key = flds[1]
    pos = length(seps[0] flds[1] seps[1]) + 1
    val = substr($0,pos)
    printf "key=<%s>\npos=<%s>\nval=<%s>\n\n", key, pos, val
}

$ printf -- ' \tFirst \t\t  Second \t Third  \t\n' | awk -f tst.awk
key=<First>
pos=<13>
val=<Second      Third          >

$ printf -- '-11...22;,;..;33-44...;\n' | awk -F'[^0-9-]+' -f tst.awk
key=<-11>
pos=<7>
val=<22;,;..;33-44...;>

おすすめ記事