我有以下文件
ID Score Other
ABR 0.98 NBNMSB
BCG 0.76 NBNMSB
CVD 0.6 NBNMSB
BCG 0.9 VSCVA
CVD 0.56 VSCVA
ABR 0.9 VSCVA
CVD 0.7 BAVSC
BCG 0.4 BAVSC
ABR 0.5 BAVSC
AAC 0.1 BAVSC
ABR 0.8 NBNMSB
BCG 0.6 NBNMSB
CVD 0.3 NBNMSB
BCG 0.7 VSCVA
CVD 0.0 VSCVA
ABR 0.1 VSCVA
CVD 0.5 BAVSC
BCG 0.8 BAVSC
ABR 1.0 BAVSC
我想排除第3列中第一次和最后一次出现的值,这样我得到一个输出:
ID Score Other
BCG 0.76 NBNMSB
CVD 0.56 VSCVA
BCG 0.4 BAVSC
ABR 0.5 BAVSC
BCG 0.6 NBNMSB
CVD 0.0 VSCVA
BCG 0.8 BAVSC
答案 0 :(得分:4)
在awk中你可以尝试这个
awk 'NR==1
{last[NR%3]=$3;lastLine[NR%3]=$0;}
last[(NR-1)%3]==last[(NR-2)%3] &&
last[(NR-1)%3]==last[NR%3]{print lastLine[(NR-1)%3]}' test
产生预期的输出:
ID Score Other
BCG 0.76 NBNMSB
CVD 0.56 VSCVA
BCG 0.4 BAVSC
ABR 0.5 BAVSC
BCG 0.6 NBNMSB
CVD 0.0 VSCVA
BCG 0.8 BAVSC
<强>解释强>
1. NR == 1 simple打印第一行
2. {last[NR%3]=$3;lastLine[NR%3]=$0;}
将最后两行和当前行存储在数组中(lastLine
)
3.通过last[(NR-1)%3]==last[(NR-2)%3] && last[(NR-1)%3]==last[NR%3]
,我们检查最后一行是否在第三列中与当前行具有相同的值,而第二行在最后一行中是否具有相同的值(即,它们是否在第3列中具有相同的值)。在这种情况下,我们打印最后一行。
答案 1 :(得分:2)
如果您有tac
(或gtac
),则可以删除第一个实例,反转文件,删除第一个(最后一个)实例并最后一次翻转文件。
$ awk '$3==p;{p=$3}' file1 | tac | awk '$3==p;{p=$3}' | tac
BCG 0.76 NBNMSB
CVD 0.56 VSCVA
BCG 0.4 BAVSC
ABR 0.5 BAVSC
BCG 0.6 NBNMSB
CVD 0.0 VSCVA
BCG 0.8 BAVSC
修改强>:
这是一个更灵活的版本。只需将c
的初始值设置为所需的列:
使用第3列:
c=3 && awk -v c=$c '$c==p;{p=$c}' file1 | tac | awk -v c=$c '$c==p;{p=$c}' | tac
使用第4栏:
c=4 && awk -v c=$c '$c==p;{p=$c}' file1 | tac | awk -v c=$c '$c==p;{p=$c}' | tac
答案 2 :(得分:2)
另一个更简单的问题是:
awk 'NR == 1; prev != $3 {prev = $3; line = 0; next}
{if (line) print line; line = $0}' foo.txt | column -t
你会得到
ID Score Other
BCG 0.76 NBNMSB
CVD 0.56 VSCVA
BCG 0.4 BAVSC
ABR 0.5 BAVSC
BCG 0.6 NBNMSB
CVD 0.0 VSCVA
BCG 0.8 BAVSC
这样做是将第3列和行存储在名为prev
和line
的变量中,如果它们不是第一次和最后一次出现,则将它们打印出来。
请注意,这只需要1次传递文件,而不是使用tac
和多次传递。
答案 3 :(得分:1)
这可能适合你(GNU sed):
sed -r '1p;$!N;/(\S+)\n.*\1$/!d;P;D' file
打印第一行reqardless(标题行)。一次读两行,如果这两行没有相同的第三列,则删除它们。否则打印第一行并附加下一行并重复。