これはバッシュ4でネイティブに実行できます。
#!/bin/bash
declare -A vals_one vals_two
while IFS=- read key val1 val2; do
if [[ ${vals_one["$key"]} ]] ; then
vals_one["$key"]=$((${vals_one["$key"]} + val1))
vals_two["$key"]=$((${vals_two["$key"]} + val2))
else
vals_one["$key"]=$val1
vals_two["$key"]=$val2
fi
done < <(cat input1.txt input2.txt)
for key in "${!vals_one[@]}"; do
printf '%s-%s-%s\n' "$key" "${vals_one[$key]}" "${vals_two[$key]}"
done
(注)このアプローチことややメモリ非効率です。よりメモリ効率の良いアプローチは、ファイルをマージする前にソートします(GNU sortは、ソートした内容がメモリに収まらない場合に一時ファイルを生成することができます。また、この後者の形態は、連想配列を必要とせず、古いはbashのバージョン(または、いくつかの適応と、他のシェル)で動作する
#!/bin/bash
function merge_inputs {
IFS=- read key val1 val2
while IFS=- read new_key new_val1 new_val2; do
if [[ $key = "$new_key" ]] ; then
val1=$((val1 + new_val1))
val2=$((val2 + new_val2))
else
printf '%s-%s-%s\n' "$key" "$val1" "$val2"
key=$new_key
val1=$new_val1
val2=$new_val2
fi
done
printf '%s-%s-%s\n' "$key" "$val1" "$val2"
}
sort input1.txt input2.txt | merge_inputs
:従って、専用メモリ内の時間で2つの行を格納するために必要。
+1美しい解決策を探しています。 – kev
これは美しいです – flatronka
美容は主観的で、時には肌だけ深く、知性が低いです。ここで、「美」とは、文字列の値を数値として扱い、定義されていない変数を増やすことができるという点にあります。変数のスペルを間違えた場合は、awkからの警告の一言もありません。文字列に数字以外のものが含まれている場合、それはちょうどゼロです。wee ... awk '{print "a" + 1}' 'はうれしく1を返します。問題はありません。あなたの「美しいプログラム」で常に「美しい入力」を使用してください。 – Kaz