我想基于多列中的匹配来过滤行。 我有(各种)4列标签分隔文件。 我需要检查第1列中的所有重复出现,检查相应的第4列,如果值不同(即使只出现一次),则打印整行(4列)。
以下是输入的示例:
function-n such_as-handheld-n 6.4623 A
function-n such_as-hash-n 6.5328 A
party-n such_as-head-n 2.5586 A
function-n such_as-headphone-n 8.0794 B
function-n such_as-health-n 3.1938 A
party-n such_as-heartbeat-n 6.5902 B
party-n such_as-heat-n 3.9708 B
zebra-n at-1-aquatic-n 10.0476 B
zebra-n become-pelican-n 12.4166 B
zebra-n behind-idea-of-concept-n 16.0319 B
zebra-n move-lion-n 12.2017 B
zebra-n such_as-1-pole-n 8.9519 B
zebra-n try-reasoning-n 12.9504 B
zooplankton-n than-1-mangrove-n 12.0638 B
因此结果如下:
function-n such_as-handheld-n 6.4623 A
function-n such_as-hash-n 6.5328 A
party-n such_as-head-n 2.5586 A
function-n such_as-headphone-n 8.0794 B
function-n such_as-health-n 3.1938 A
party-n such_as-heartbeat-n 6.5902 B
party-n such_as-heat-n 3.9708 B
as“function-n”和“party-n”是Column1中第4列中唯一具有不同值的值。
我看过这篇关于使用awk基于多列here丢弃行的帖子。 代码(由@Steve提出)如下:
FNR==NR {
array[$0]++
next
}
{
counter = 0
for (i in array) {
split(i, holder, FS)
if (holder[1] == $1) {
counter++
}
}
if (counter >= 2) {
print
}
}
$ awk -f script.awk file.txt{,}
除了2列数据外,此代码完全符合我的要求。 我试图修改脚本的一部分来比较第4列,如下所示:
{
counter = 0
for (i in array) {
split(i, holder, FS)
if (holder[1] == $4) {
counter++
}
然而,它不起作用。任何人都可以提供有关如何修改此脚本的见解,以便我可以获得所需的结果吗?
或许某人有更有效/优化的方法来处理这个问题? 谢谢。
答案 0 :(得分:2)
我认为你必须非常努力地使用awk。在读完每一行之前,您无法开始打印,我认为您需要的数据结构有点超出了awk提供的范围。您可以使用更高级别的语言:Python,Perl,Ruby。
这是红宝石1.9.3:
ruby -F"\t" -ane '
BEGIN {
f4 = Hash.new {|h,k| h[k] = Hash.new}
lines = Hash.new {|h,k| h[k] = Array.new}
}
f4[$F[0]][$F[-1]] = 1
lines[$F[0]] << [$., $_]
END {
output = []
f4.each_pair do |key, subhash|
if subhash.length > 1
lines[key].each {|pair| output[pair[0]] = pair[1]}
end
end
puts output
}
'
的Perl:
perl -F"\t" -ane '
$f4{$F[0]}{$F[-1]} = 1;
push @{$lines{$F[0]}}, [$., $_];
END {
@output=();
while (($key, $subhash) = each %f4) {
if (keys(%$subhash) > 1) {
$output[$_->[0]] = $_->[1] for @{$lines{$key}};
}
}
print @output;
}
'
答案 1 :(得分:0)
可能的解决方案(使用awk)如下:
$ awk'NR == FNR {if(A [$ 1]!= $ NF&amp;&amp; A [$ 1]){B [$ 1] ++} A [$ 1] = $ NF; next} {if (B [$ 1]){print}}'输入输入&gt;输出