次のように、多くの行と5つの数値列を含むファイルがあります。
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
...
1行目と3行目の数字の合計をこの方法で取得するには:1 + 11、2 + 12、3 + 13、4 + 14、5 + 15これは私が最終的に見たいものは何をすべきかを意味し12 14 16 18 20
ます。それか。
答え1
ソリューション1
#!/bin/bash
{ read -ra line1; read _; read -ra line3; }
for i in "${!line1[@]}"; do
result+=("$(( ${line1[i]} + ${line3[i]} ))")
done
printf %s\\n "${result[*]}"
例:
$ bash script < yourfilename
12 14 16 18 20
$
スクリプトの説明
{ read -ra line1; read _; read -ra line3; }
この部分はファイルの最初の3行を読み取り、最初の2行だけを保持します。また、配列line1とline3に分割します。標準入力からのデータストリーミングを想定します。これを行う方法の例を参照してください。
for i in "${!line1[@]}"; do result+=("$(( ${line1[i]} + ${line3[i]} ))"); done
この部分は、2つの配列のうちの1つの要素を繰り返し、line1とline2の同じ要素を合計します。結果は、resultという名前の新しい配列に保存されます。
printf %s\\n "${result[*]}"
計算された配列要素をスペースで区切って印刷します。
ソリューション2
入力に必要に応じて5つの列があると仮定してループを防ぐもう1つの解決策は次のとおりです。
#!/bin/bash
{ read a b c d e; read _; read v w x y z; }
echo "$((a+v)) $((b+w)) $((c+x)) $((d+y)) $((e+z))"
例:
$ cat yourfilename
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
...
$ bash script < yourfilename
12 14 16 18 20
$
スクリプトの説明
{ read a b c d e; read _; read v w x y z; }
1行(または3行)の数字を変数a〜e(またはv〜z)として読み込みます。
echo "$((a+v)) $((b+w)) $((c+x)) $((d+y)) $((e+z))"
要求時にスペースで区切られた変数の合計を印刷します。
答え2
$ sed -n '1p;3p' file | datamash -W sum 1-5
12 14 16 18 20
まずsed
ライン1と3のみが出力されます。その後、GNUに入力して、datamash
列1から5までの個々の列を合計するように指示されます。これは、連続したスペースがフィールド区切り文字として扱われることを-W
示します。datamash
出力はタブで区切られます。スペースで区切られた出力を取得するには、--output-delimiter=' '
次のオプションを使用しますdatamash
。
$ sed -n '1p;3p' file | datamash -W --output-delimiter=' ' sum 1-5
12 14 16 18 20
答え3
awk 'NR==1 || NR==3 { for (i=1; i<=NF; i++) a[i]+=$(i)}END{for (i in a) printf "%s ", a[i]; print ""}'
例:
$ awk 'NR==1 || NR==3 { for (i=1; i<=NF; i++) a[i]+=$(i)}END{for (i in a) printf "%s ", a[i]; print ""}'' yourfilename
12 14 16 18 20
$
編集:3行目以降のファイルの行の読み取りを中止するには、早く終了します。ただし、10,000行未満を含むファイルでは大きな違いはありません。
awk 'NR==1 {split($0,a)} NR==3 {for (i in a) printf "%s ", a[i]+$i; print ""; exit}'
あなたの例で動作していることを証明してください。
$ cat yourfilename
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
...
$ awk 'NR==1 {split($0,a)} NR==3 {for (i in a) printf "%s ", a[i]+$i; print ""; exit}' yourfilename
12 14 16 18 20
$