sed または nawk を使用した列の代替値の合計の計算

sed または nawk を使用した列の代替値の合計の計算

foo.txt:

1  10     11
2   20     22
3   30     32
4   40     42
5   50     52
6   60     62
7   70     72
8   80     82
9   90     92
10  100   110

期待するOut.txt:

1  10     11
2   20     22
3   30     32
4   40     42
5   50     52
6   60     62
7   70     72
8   80     82
9   90     92
10  100   110
25  250   275   #Line 11
30  300   330   #Line 12
45  550   595  #Line 13

11行は1行から始まり1、2、3列の交互行の合計であり、12行は2行の合計で始まる1、2、3列の交互行の合計です。 13行は11行と12行の列を合わせたものです。 KSHとSolaris 5.10を使用していますが、入力ファイルの値が連続しない場合もあり、3桁の整数を超えない場合もあります。私の入力ファイルには10行しかありません。この目標を達成する方法は?

答え1

$ awk -v OFS='\t' '{for (i=1;i<=NF;i++) {s[2-NR%2,i]+=$i;s[3,i]+=$i;};$1=$1;print} END{for (n=1;n<=3;n++) print s[n,1],s[n,2],s[n,3]}' foo.txt 
1       10      11
2       20      22
3       30      32
4       40      42
5       50      52
6       60      62
7       70      72
8       80      82
9       90      92
10      100     110
25      250     259
30      300     318
55      550     577

上記はGNU awkとLinuxでテストされました。

どのように動作しますか?

  • -v OFS='\t'

    オプション:出力をタブ区切りに設定します。

  • {for (i=1;i<=NF;i++) {s[2-NR%2,i]+=$i;s[3,i]+=$i;}; $1=$1; print}

    これは各列を繰り返してその値を配列に追加しますs。各列にi偶数行が追加され、s[2,i]奇数行が追加されますs[1,i]。すべての行の列iがに追加されますs[3,i]

    その後、ラインを印刷します。

  • END{for (n=1;n<=3;n++) print s[n,1],s[n,2],s[n,3]}

    ファイルの終わりに達すると、結果が印刷されます。まず、奇数行を印刷し()、n=1偶数行を印刷してから(n=2)、最後に合計を印刷します(n=3)。

サン/ソラリス

Sun/Solaris のデフォルト awk に問題があるという報告を何度も受けました。試してみてください:

nawk -v OFS='\t' '{for (i=1;i<=NF;i++) {s[2-NR%2,i]+=$i;s[3,i]+=$i;};$1=$1;print} END{for (n=1;n<=3;n++) print s[n,1],s[n,2],s[n,3]}' foo.txt 

または:

/usr/xpg4/bin/awk -v OFS='\t' '{for (i=1;i<=NF;i++) {s[2-NR%2,i]+=$i;s[3,i]+=$i;};$1=$1;print} END{for (n=1;n<=3;n++) print s[n,1],s[n,2],s[n,3]}' foo.txt 

または:

/usr/xpg6/bin/awk -v OFS='\t' '{for (i=1;i<=NF;i++) {s[2-NR%2,i]+=$i;s[3,i]+=$i;};$1=$1;print} END{for (n=1;n<=3;n++) print s[n,1],s[n,2],s[n,3]}' foo.txt 

答え2

awk代わりにこれを使用したいと思いますsed。これはawkこれを行うスクリプトです。

awk '
    (NR%2) == 1 {
        odd_col_1 += $1;
        odd_col_2 += $2;
        odd_col_3 += $3;
        print $0;
    }
    (NR%2) == 0 {
        even_col_1 += $1;
        even_col_2 += $2;
        even_col_3 += $3;
        print $0;
    }
    END {
        print odd_col_1, odd_col_2, odd_col_3;
        print even_col_1, even_col_2, even_col_3;
        print odd_col_1+even_col_1, odd_col_2+even_col_2, odd_col_3 + even_col_3;
    }
' foo.txt

これは、「NR」レコード番号の組み込み変数、awkテキストファイルをフィールドで区切る方法、および「END」構造を利用します。

答え3

まあ、私はこの問題に対する非常に基本的な解決策を自分で見つけました。しかし、誰かがより良い答えを持っていることを願っています。

#remove even lines
sed -i '0~2d' foo.txt > oddlines

#oddlines sum
awk '{a=a+$1}{b=b+$2}{c=c+$3}END{print a,b,c}' oddlines > oddlines_sum

#remove even lines
sed -i '1~2d' foo.txt > evenlines

#evenlines sum
awk '{a=a+$1}{b=b+$2}{c=c+$3}END{print a,b,c}' evenlines > evenlines_sum

#combine 
cat evenlines_sum >> oddlines_sum

#for total sum of foo.txt
awk '{a=a+$1}{b=b+$2}{c=c+$3}END{print a,b,c}' foo.txt > foo_sum

#final output
cat oddlines_sum >> foo.txt
cat foo_sum >> foo.txt`

私は私の解決策が非常に基本的であることを知っています。しかし、私は最善を尽くしました。

答え4

sed '   1x;1s/^/654321/;1x;N;y/ /\n/;G;:t
        s/\([0-9]*\)\n*\n\(.*\)\(.\)/l\3\1+s\3 \2/;tt
        p;$!d;g;s/./l&/g;s/$/fcl3l6+l2l5+l1l4+f/' file |
dc 2>/dev/null |sed '11,$N;/\n/N;s/[^0-9] */\t/g' file -

これはあなたに役立ちます。内部ストリームを使用してdc電卓/コンパイラのいくつかのマクロ前処理を処理することによって機能します。sed

基本的にsed言うdc bcコンパイラ - Solarisシステムに存在する必要があります)6つの値を追跡し、1行の入力行すべてをロードし、各列の値を増やした後に結果を再保存します。最後の入力行にもう一度呼び出すようにsed指示し、6つの値をすべてstdoutに出力します。dc13行の合計を取得するには、保存された合計を再度呼び出して加算するだけです。

l3l6+...f

最初の行で任意の配列から値をロードしようとすると、配列が空で警告が発生するため、dcstderrをダンプします。残りの時間は空ではなく、必要に応じて保存/復元するため、これは意味がありません。/dev/nulll[123456]

最後に、もう一つはsedすべてを一つにまとめます。dc出力を尾部に追加します。fileすべてのスペースを1行に1つのタブに置き換えます。\tここではエスケープ文字を使用していますが、実際のスクリプトではリテラル<tab>文字でなければなりません)

出力

1       10      11
2       20      22
3       30      32
4       40      42
5       50      52
6       60      62
7       70      72
8       80      82
9       90      92
10      100     110
25      250     259
30      300     318
55      550     577

関連情報