Linux shell脚本将列读入变量然后添加属性

时间:2013-03-20 18:11:32

标签: linux parsing shell variables

我的文件test.txt看起来像这样:

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

我正在尝试创建一个

的shell脚本
  1. 读取每一行并将数据分为两列,分别为变量var1和var2
  2. 如果每行中的var2相同,则在这些行中添加var1。
  3. 将文件输出到文本文件中。
  4. 结果应该是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
    

1 个答案:

答案 0 :(得分:2)

使用awk很容易:

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

如果你想用bash 4.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