2

我有一个文件 test.txt,如下所示:

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

我正在尝试创建一个 shell 脚本

  1. 读取每一行并将两列中的数据放入变量 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; }'

如果你想用bash4.x(不是 3.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[@]}符号在手册的Shell Parameter Expansion部分中进行了描述,甚至在Arrays部分中也没有暗示。如果您知道在哪里查找,信息就在那里。

如果你想处理任意数量的输入文件(就像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
}

这不是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 回答