我想比较同一文件中的多列,以查看我在哪一行有差异,在这种情况下,前四列。该文件如下所示:
Column1 Column2 Column3 Column4 Column5
AA AA AA AA AA
GG GG GG GG GG
CC GC CC CC CC
CC TT CC GC TT
如果我做了这样的事情:
awk -F"\t" '{if ($1==$2) print $1, $2; else print NR}' file.txt
我得到下一个输出:
1
AA AA
GG GG
4
5
但是,如何用简单的语法同时比较前四列呢?我尝试过这样的事情:
awk -F"\t" '{if ([$2,$3,$4]==$1) print $1, $2, $3, $4 ; else print NR}' File.txt
,但是它不起作用。
我的预期输出应该是:
1
AA AA AA AA
GG GG GG GG
4
5
我的文件有多于四列,所以我想比较列的组(在这种情况下,从列1到列4),并且如果这四个列具有相同的字符,则只打印这四个列;如果它们的行数相同,则只打印行数有差异。
我该如何实现?
答案 0 :(得分:0)
我将使用循环逐步浏览您的专栏:
$ awk '{x=0;for(i=1;i<NF;i++){if($i!=$(i+1)){x=1}} print x?NR:$0}' input.txt
或者,为便于阅读:
{
x=0 # initialize the flag for each line
for (i=1;i<NF;i++) { # step through the fields
if ($i!=$(i+1)) { # test for a match with the next field
x=1 # and set a flag if we see different content.
}
}
print x ? NR : $0 # print NR or the first field depending on flag value
}
此步骤逐步遍历所有字段(不仅仅是四个字段),将每个字段的内容与其后面的字段的内容进行比较。如果任何时候字段不匹配,则会设置一个标志。
最终语句中的三元运算符根据标志选择要显示的输出。
请注意,您期望的输出似乎从行首开始就修剪了空格。如果您确实需要这样做,可以在sub(/^[[:space:]]+/,"")
语句之前print
。
答案 1 :(得分:0)
这可能是您想要的:
$ awk '{
sub(/^[[:space:]]+/,"")
delete uniq
for (i=1;i<=4;i++) {
uniq[$i]
out=(i>1 ? out OFS : "") $i
}
print (length(uniq) > 1 ? NR : out)
}' file
1
AA AA AA AA
GG GG GG GG
4
5
这需要awk,它可以使用length(array)
获取GNU awk可以使用的数组中元素的数量,我不确定其他元素。
假设您确实有一个支持length(array)
的awk,那么仅当您在某些时候需要唯一值计数时(才这样做)还是使用a table of requirements比较相邻值才重要我的提供),而不是仅是一个/否(是否都提供1个或多个)。例如,如果您要打印每行中存在多少唯一值,则在打印行号后,这些值并不是唯一的:
awk '{
sub(/^[[:space:]]+/,"")
delete uniq
for (i=1;i<=4;i++) {
uniq[$i]
out=(i>1 ? out OFS : "") $i
}
numUniq = length(uniq)
print (numUniq > 1 ? NR OFS numUniq : out)
}' file
1 4
AA AA AA AA
GG GG GG GG
4 2
5 3
btw,如果您使用的awk不支持length(array)
,则可以编写自己的awk:
function alength(a, i,c) {for (i in a) ++c; return c+0}
,然后将其称为alength(array)
。
答案 2 :(得分:0)
如果使用关联数组,并在进行线性传递时增加每个值的计数。您可以简单地:
$ awk '{delete x; for(i=1;i<=NF;i++) x[$i]++; if (x[$NF]==NF) print $0; else print NR;}' file.txt
1
AA AA AA AA
GG GG GG GG
4
5