0

我有一个看起来像这样的文件:

1    a
3    b
2    b
9    a
0    a
5    c
8    b

我想要...

  1. 仅打印第 2 列中存在的每个元素的最后一个实例及其在第 1 列中的对应值;
  2. 根据第 2 列的内容,按字母顺序对 1. 的结果进行排序;
  3. 在第 1 列之前的输出中添加第三列,其内容取决于第 2 列的值;
  4. 用回车替换制表符;

...所有这些都在一个 awk 程序中。

所以最终的输出会是这样的:

x
0
a
x
8
b
y
5
c

我成功地完成了这一切,但使用了两个 awk 程序和一个外部命令:

awk -F '\t' '{
    value[$2]=$2"\t"$1 }
    END { for (i in value) print value[i]
    }' | \
sort -dfb | \
awk -F '\t' '{
if ($1 == "a" || $1=="b") print "x\n"$2"\n"$1
if ($1 == "c") print "y\n"$2"\n"$1
}'

一个更简单的方法是按字母顺序对第一个 awk 程序的数组进行排序。这将允许将第二个 awk 程序的内容合并到第一个中。但是,我不知道我该怎么做。任何想法 ?

4

2 回答 2

1

GNU awk <= 3

WHINY_USERS= awk 'END {
  for (R in r)
    printf "%s\n%s\n%s\n", 
      (R ~ /^[ab]$/ ? "x" : "y" ), r[R], R
  }
{
  r[$2] = $1
  }' infile

GNU awk >= 4

awk 'END {
  PROCINFO["sorted_in"] = "@ind_str_asc"
  for (R in r)
    printf "%s\n%s\n%s\n", 
      (R ~ /^[ab]$/ ? "x" : "y" ), r[R], R
  }
{
  r[$2] = $1
  }' infile
于 2012-09-03T12:43:55.337 回答
0

这是六年前的事了,我在这里回复……如果我理解请求,值列表是:

1    a
3    b
2    b
9    a
0    a
5    c
8    b

仅针对第 2 列的 1 个实例进行处理,第 1 列的关联值最低。期望的结果:

0    a
2    b
5    c

通过使用 2 种而不是 awk,该过程似乎是最简单的。捕获 FILE 中的值列表,以下命令将显示结果:

$ sort +0 -1n FILE|sort +1 -2 -u
0    a
2    b
5    c

每个唯一列 2 的相反顺序或最高列 1 值

$ sort +0 -1nr FILE|sort +1 -2 -u
9    a
8    b
5    c

如果 awk 优先于排序,则以下 awk 程序可以执行操作以对每个唯一的第 2 列条目取最小值:

$ awk '{if($2 in COL2){if(COL2[$2]>$1){COL2[$2]=$1}}else{COL2[$2]=$1}}END{for(I in COL2){print COL2[I],I}}' FILE
0 a
2 b
5 c

相反的顺序,每个唯一的第 2 列条目的第 1 列的最大值是通过将“>”替换为“<”来完成的:

$ awk '{if($2 in COL2){if(COL2[$2]<$1){COL2[$2]=$1}}else{COL2[$2]=$1}}END{for(I in COL2){print COL2[I],I}}' FILE
9 a
8 b
5 c

可能我错过了要求,6年后的反应不是很及时。我一直在寻找别的东西,发现了这个,无法帮助自己。

于 2019-04-12T19:39:12.463 回答