2

次のようなファイルtest.txtがあります。

2092 Mary
103 Tom
1239 Mary
204 Mark
1294 Tom
1092 Mary

シェルスクリプトを作成しようとしています

  1. 各行を読み取り、2つの列のデータを変数var1とvar2に入れます
  2. 各行のvar2が同じである場合は、それらの行にvar1を追加します。
  3. ファイルをテキストファイルに出力します。

結果は、var2列の一意の値になります。これが私がこれまでに持っているものです:

#!/bin/sh
#!/usr/bin/sh
cat test.txt| while read line;
do
$var1=$(echo $line| awk -F\; '{print $1}')
$var2=$(echo $line| awk -F\; '{print $2}')

各行の変数を参照して比較するにはどうすればよいですか?
期待される出力は次のようになります。

4423 Mary
1397 Tom 
204  Mark
4

1 に答える 1

2

使い方awkは簡単です。

awk '{sum[$2] += $1} END {for (i in sum) printf "%4d %s\n", sum[i], i; }'

bash(3.xではなく)4.xでそれを実行したい場合は、次のようにします。

declare -A sum
while read number name
do
    ((sum[$name] += $number))
done

for name in "${!sum[@]}"
do
    echo ${sum[$name]} $name
done

ここでの構造は基本的にawkスクリプトと同形ですが、表記上は少し便利ではありません。名前を連想配列へのインデックスとして使用して、標準入力から読み取りますsum${!sum[@]}表記は、マニュアルの「シェルパラメータ拡張」セクションで説明されており配列のセクションではほのめかされていませ。あなたがどこを見るべきか知っているなら、情報はそこにあります。

awk(スクリプトのように)任意の数の入力ファイルを処理する場合は、を使用catしてデータを収集する必要があります。

cat "$@" |
{
declare -A sum
while read number name
do
    ((sum[$name] += $number))
done

for name in "${!sum[@]}"
do
    echo ${sum[$name]} $name
done
}

これは、引数なし(標準入力の読み取り)、1つの引数、または多数の引数を処理するため、UUOCではありません。

すべてのスクリプトについて、出力を番号または名前の順序で並べ替える場合は、スクリプトの出力に適切なものを適用しsortます。

script file1 file2 file3 | sort -k 1,1n     # By sum increasing order
script file1 file2 file3 | sort -k 1,1nr    # By sum decreasing order
script file1 file2 file3 | sort -k 2,2      # By name increasing order
script file1 file2 file3 | sort -k 2,2r     # By name decreasing order
于 2013-03-20T19:20:26.897 に答える