0

我有一个需要一些操作的大型数据库文件。本质上,我需要避免由“|”分隔的重复字段一 为了:

-- TITLE1 | TITLE2   |T3   |TITLE4|TITLE5 
----------|----------|-----|------|---------------
--
DATA1   | SAME     |     |      |  blah blah
ELIGIBLE  | x1 
DATA1   | SAME     |     | blah |  blah
ELIGIBLE  | x2 
DATA1   | SAME     |     | blah |  blah blah
ELIGIBLE  | x2 
DATA2   | SAME     |     |      |  blah blah
ELIGIBLE  | y1 
DATA2   | SAME     |     | blah |  blah
ELIGIBLE  | y2
DATA2   | SAME     |     | blah |  blah blah blah blah
ELIGIBLE  | y2
DATA3   | SAME     |     |      |  blah blah
ELIGIBLE  | z1
DATA3   | SAME     |     | blah |  blah
ELIGIBLE  | z2
DATA3   | SAME     |     | blah |  blah blah blah blah
ELIGIBLE  | z2

我正在使用的代码是

BEGIN{ FS = "|" }
{
count[$1]++;
if (count[$1] == 1)
first [$1] = $0;
if (count[$1] > 1)
print first[$1]
NR==1;
}

但它给了我输出:

-- TITLE1 | TITLE2   |T3   |TITLE4|TITLE5 
----------|----------|-----|------|---------------
--
DATA1   | SAME     |     |      |  blah blah
ELIGIBLE  | x1 
DATA2   | SAME     |     |      |  blah blah
DATA3   | SAME     |     |      |  blah blah

我更喜欢这样的输出:

-- TITLE1 | TITLE2   |T3   |TITLE4|TITLE5 
----------|----------|-----|------|---------------
--
DATA1   | SAME     |     |      |  blah blah
ELIGIBLE  | x1 
DATA2   | SAME     |     |      |  blah blah
ELIGIBLE  | y1 
DATA3   | SAME     |     |      |  blah blah
ELIGIBLE  | z1 

我并不真正关心标题栏,但需要它来显示概述的数据。对不起,业余的解释,但任何解决方案的帮助将不胜感激。我是 linux 命令行脚本的新手,所以如果有人也能解释为什么我的答案是错误的,我将不胜感激。我不限于 awk,可以使用任何命令解决方案。我只是想尝试使用 awk 的解决方案。

4

2 回答 2

0

你可以试试这个:

awk -F\| '(printed!=0 && /ELIGIBLE/) {print; printed=0;} (!seen[$1] && $1 !~ /ELIGIBLE/) { print; printed = 1; seen[$1] = 1;  }' 

尽管几乎可以肯定有更好的方法。

ETA:这里有一个很好的 Awk 教程和网络上的其他几个教程,还有一些好书。但基本上,awk 程序是一系列模式和代码块,可在与该模式匹配的每条记录(默认情况下为行)上运行。

awk '/foo/          { do this for lines that contain "foo" anywhere }
     ($1 == "bar")  { do this for lines whose first field is exactly "bar' }
     ($NF ~ /baz/)  { do this for lines whose last field contains "baz" }
     (NF == 1)      { do this for lines with exactly one field }
     (NR == 10)     { do this only on the 10th line }'

如果没有模式,则该块在每一行上运行。

awk '{print $NF}'   # print the last field of every line

如果没有块而只有一个模式,那么匹配的行将被原封不动地打印出来:

awk '/foo/'      # same as grep foo

在处理任何输入之前运行标记为 BEGIN 的块;处理完所有输入后运行标记为 END 的块。

awk 'BEGIN { t = 0 } {t += $NF} END { print t }'   # print total of last column 

但实际上未初始化的变量在算术中被视为 0,因此您可以跳过初始化:

awk '{t += $NF} END {print t}'

某些版本的 awk 需要;在模式/块对之间使用分号或换行符

于 2013-05-14T15:16:09.533 回答
0

此行适用于您给定的示例。(数据已排序,oneline 数据,oneline Eligible...)如果格式发生变化,不保证适用于您的真实数据。你必须自己测试它。

标题/标题被跳过。

awk -F'|' '!(NR%2){next}$1 in a{next}{print;a[$1];getline;print}' file

试试看:

kent$  awk -F'|' '!(NR%2){next}$1 in a{next}{print;a[$1];getline;print}' file
DATA1   | SAME     |     |      |  blah blah
ELIGIBLE  | x1 
DATA2   | SAME     |     |      |  blah blah
ELIGIBLE  | y1 
DATA3   | SAME     |     |      |  blah blah
ELIGIBLE  | z1
于 2013-05-14T15:39:52.460 回答