awk
関数はファイル名で次のようになりますfun.awk
。
{
print small()
}
function small()
{
a[NR]=$0
smal=0
for(i=1;i<=3;i++)
{
if( a[i]<a[i+1])
smal=a[i]
else
smal=a[i+1]
}
return smal
}
コンテンツawk.write
:
1
23
32
コマンドは次awk
のとおりです。
awk -f fun.awk awk.write
何の結果も出ませんか?なぜ?
修正する
{
print f()
}
function f()
{
if(NR==1){s=$0}
if($0<p)
{s=$0}
{p=$0}
{ return s}
}
ベストアンサー1
両方のバージョンのコードは、small
入力ファイルの各行で関数を実行します。ファイル全体の最小数を見つけるには、ファイル全体を処理して最後に一度だけ関数を実行します。更新された関数は正しく機能し、正しい出力を3回印刷するように見えますが、これは最小数が最初の行にあるためです。このファイルで実行すると:
$ cat awk.write
10
9
8
以下の結果が出力されます。
awk -f fun.awk awk.write
10
9
8
これは、関数を実行するたびに現在の行番号が保存されている行番号よりも少なく印刷されるためです。ブロックを使用END{}
し、そこから関数を実行する必要があります。
function small(){
for(i=1;i<=NR;i++)
{
## If smal is not set or if it is greater than a[i]
if(smal=="" || a[i]<=smal)
smal=a[i]
}
return smal
}
{
## NR is the current line number. This saves the current line
## in the array a.
a[NR]=$0
}
## This will be executed only after everything has been read
END{
print small()
}
NR
また、代わりに使用して3
複数の行で動作するように一般化しました。次のようにさらに簡素化できます。
{
if(small=="" || $0<small){
small=$0
}
}
END{print small}
これは次の行と同じです。
awk '(small=="" || $0<small){small=$0}END{print small}' awk.write