1

私は、次のような数値を含むソートされたファイルを持っています

foo 2.3
bar 2.6
baz 4.7

次のように、行のパーセンタイルを最後の列に入れるワンライナーが必要です

foo 2.3 0.3333
bar 2.6 0.6666
baz 4.7 1.0000

ありがとうございました。

4

3 に答える 3

2
$ awk 'c=NR-FNR{printf "%s %.4f\n",$0,FNR/c}' file file
foo 2.3 0.3333
bar 2.6 0.6667
baz 4.7 1.0000
于 2013-01-16T17:22:33.767 に答える
2

行の割合を意味していると思います。これには、最初に行数を知る必要があります。

awk を使用して 2 パス ソリューションとして実行する 1 つの方法を次に示します。

 awk 'FNR == NR { tot=NR; next } { printf( "%s %.4f\n", $0, FNR/tot) }' file file 

出力:

foo 2.3 0.3333
bar 2.6 0.6667
baz 4.7 1.0000

最初のブロックはFNR == NR、最初のパスの間だけアクティブになります。2 番目のブロックは印刷を処理します。

ファイルの長さを決定するその他の方法

NR-12 番目のパスを開始するときに使用します ( FNR != NR):

awk 'FNR != NR { if(!tot) tot=NR-1; printf( "%s %.4f\n", $0, FNR/tot) }' file file

wcawk を実行する前に使用します。

awk -v tot=$(wc -l < file) '{ printf( "%s %.4f\n", $0, FNR/tot) }' file
于 2013-01-16T10:01:17.877 に答える
1

@thor ソリューションは優れていますが、ファイルを 2 回トラバースする必要はありません。代わりに、メモリ自体の内部で実行できます。

awk '{a[NR]=$0;}END{for(i=1;i<=NR;i++)print a[i],i/NR;}' your_file

テスト済み:

> cat temp
foo 2.3
bar 2.6
baz 4.7
> awk '{a[NR]=$0;}END{for(i=1;i<=NR;i++)print a[i],i/NR;}' temp
foo 2.3 0.333333
bar 2.6 0.666667
baz 4.7 1

精度について具体的な場合は、以下を使用してください。

> awk '{a[NR]=$0;}END{for(i=1;i<=NR;i++)printf("%s %0.4f\n",a[i],i/NR);}' temp
foo 2.3 0.3333
bar 2.6 0.6667
baz 4.7 1.0000
于 2013-01-16T13:42:03.637 に答える