Database awk-仅打印副本的第一行及其下一行
我有一个大的数据库文件,需要一些操作。基本上,我需要避免重复字段1,该字段由“|”分隔,用于:Database awk-仅打印副本的第一行及其下一行,database,linux,command-line,awk,matching,Database,Linux,Command Line,Awk,Matching,我有一个大的数据库文件,需要一些操作。基本上,我需要避免重复字段1,该字段由“|”分隔,用于: -- TITLE1 | TITLE2 |T3 |TITLE4|TITLE5 ----------|----------|-----|------|--------------- -- DATA1 | SAME | | | blah blah ELIGIBLE | x1 DATA1 | SAME | | blah | blah ELIG
-- 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解决方案。您可以尝试以下方法:
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的某些版本需要分号
模式/块对之间的代码>或换行符这一行适用于给定的示例。(数据已排序,一行数据,一行合格…)如果格式更改,则不保证使用真实数据。你必须自己测试一下
跳过标题/标题
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
因此,您希望保留具有给定标题1的第一行数据,并丢弃其余数据,即使它们具有不同的标题5等?正确,并将符合条件的行保留在其下方。此解决方案非常有效,非常感谢!您能解释一下如何使用awk排除/包含文本吗。抱歉,我正在学习,仅用于字段匹配。