perl -F, -lane '
exists $h{$F[0]} or $h[$h{$F[0]}=@h]=$_;
$h=$_; /,false$/ or $_=$h for $h[$h{$F[0]}];
END{ print for @h; }
' duplicates.file
Estruturas de dados:
- Hash
%h
cujas chaves são os primeiros campos (AAA, BBB, CCC etc.) e os valores correspondentes são números que indicam a ordem em que as chaves foram encontradas. Assim, por exemplo, chave AAA => 0, chave BBB => 1, chave CCC => 2.
- Matriz
@h
cujos elementos são linhas contidas na ordem de impressão. Portanto, se true e false forem encontrados nos dados, o valor false entrará na matriz. OTW, se houver um tipo de dados, isso estaria presente.
Outra maneira é usar o GNU sed:
sed -Ee '
G
/^([^,]*),(false|true)\n(.*\n)?\1,\2(\n|$)/ba
/^([^,]*)(,true)\n(.*\n)?\1,false(\n|$)/ba
/^([^,]*)(,false)\n((.*\n)?)\1,true(\n|$)/{
s//\3\1\2\5/;h;ba
}
s/([^\n]*)\n(.*)$/\2\n\1/;s/^\n*//
h;:a;$!d;g
' duplicates.file
FWIW, o código equivalente POSIX para o código GNU-sed acima está listado abaixo:
sed -e '
G
/^\([^,]*\),\(false\)\n\(.*\n\)\{0,1\}\1,\2$/ba
/^\([^,]*\),\(false\)\n\(.*\n\)\{0,1\}\1,\2\n/ba
/^\([^,]*\),\(true\)\n\(.*\n\)\{0,1\}\1,\2$/ba
/^\([^,]*\),\(true\)\n\(.*\n\)\{0,1\}\1,\2\n/ba
/^\([^,]*\),true\n\(.*\n\)\{0,1\}\1,false$/ba
/^\([^,]*\),true\n\(.*\n\)\{0,1\}\1,false\n/ba
/^\([^,]*\)\(,false\)\n\(\(.*\n\)\{0,1\}\)\1,true$/{
s//\3\1\2/
h
ba
}
/^\([^,]*\)\(,false\)\n\(\(.*\n\)\{0,1\}\)\1,true\n/{
s//\3\1\2\n/
h
ba
}
y/\n_/_\n/
s/\([^_]*\)_\(.*\)$/\2_\1/;s/^_*//
y/\n_/_\n/
h;:a;$!d;g
' duplicates.file
Explicação
- Neste método, armazenamos o resultado a ser finalmente impresso no espaço de espera.
- Para cada linha lida, anexamos o espaço de espera ao espaço do padrão para examinar a linha atual vis-à-vis o estado existente do espaço de espera.
- Agora, cinco coisas podem acontecer durante essa comparação:
- a) A linha atual corresponde a algum lugar da linha de espera e false: false.
- [AÇÃO] Como o mesmo estado falso é encontrado, não faça nada.
- b) A linha atual corresponde a algum lugar da linha de espera e true: true.
- [AÇÃO] Como o mesmo estado verdadeiro é encontrado, não faça nada.
- c) A linha atual corresponde a algum lugar da linha de espera e true: false.
- [AÇÃO] Como já existe um estado falso, não faça nada.
- d) A linha atual corresponde a algum lugar da linha de espera e false: true.
- [AÇÃO] Isso envolve algum trabalho, pois precisamos substituir a linha falsa exatamente na mesma posição em que a verdadeira está localizada.
- e) A linha atual NÃO corresponde a nenhum lugar da linha de espera.
- [AÇÃO] Mova a linha atual até o fim.
Resultados
AA,false
BB,false
CC,false
DD,true
true
se for a primeira instância da primeira coluna?