Isso mostrará os números das linhas inválidas:
sed -n '/\([a-z]\+\).*_KO/b;/\([a-z]\+\)_KO.*/b;=' input_file
Mas não lida com vários "_KO" em uma linha.
Isso deve ser mais confiável e portátil:
awk '{for(i=1;i<=NF;i++)if((s=$i)~/^([a-z]+)_KO/){sub(/_KO$/,"",s);o=0;for(j=1;j<=NF;j++)if($j==s)o=1;if(!o)printf"line %d unmatched %s\n",NR,s}}' input_file
Isso é mais complicado, mais eficiente e suporta vários padrões, mas dependendo da classificação, as configurações de localidade podem afetar seu sucesso:
ruby -nae '$F.sort!.select!{|v|v=~/^[a-z]+(_KO)?$/};$F.each_with_index{|v,k|puts"line #{$.} unmatched #{v}"if v[/^([a-z]+)_KO$/]and$F[k-1]!=$1}' input_file
Basicamente o mesmo que a solução awk
acima, mas parece menos detalhado em perl
:
perl -nae 'for$k(grep/^[a-z]+_KO$/,@F){print"line $. unmatched $k\n"unless grep{$_ eq substr$k,0,-3}@F}' input_file