【问题标题】:Linux shell script read columns into variable and then add the attributeLinux shell脚本将列读入变量,然后添加属性
【发布时间】:2013-03-20 18:11:31
【问题描述】:

我有一个文件 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

【问题讨论】:

  • 如何使用sort -s -n k 1 然后-u 来获取唯一值?
  • 你能添加预期的输出吗?谢谢
  • 没有done?和$var1=,你的意思可能是var1=...。最后,不需要以如此复杂的方式分割线。 while read num name; do ... ; done < test.txt。最后,最后,同意 fedorqui 的观点,即 sort 可以满足您的需求,除非这只是您的问题的草图。在没有sort 和/或uniq 的情况下在shell 代码中实现唯一性并非易事。祝你好运!

标签: linux parsing shell variables


【解决方案1】:

使用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

【讨论】:

  • 您需要bash 4.2 和lastpipe 选项才能让sum 在while 循环之后可见。不过,for f; do while ...; done < "$f"; done 的外部循环应该可以工作。
  • 或者while read number name; do ...; done < <( cat "$@" ),与我之前的评论不同,它也应该使用零参数。
  • @chepner: 哦——德拉特!不测试“增强”总是很危险的,即使是简单的。谢谢 — 我会按照我的方式修复它,使用 { ... } 将脚本的操作部分分组到一个单元中,以重定向 cat 输出。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-26
  • 1970-01-01
  • 2021-09-12
  • 2021-11-29
  • 2013-02-04
  • 1970-01-01
相关资源
最近更新 更多