Se você está procurando por aquelas linhas que têm o mesmo name AND group_id , você poderia fazer algo assim (supondo que você esteja em um * nix OS, você não diz na sua pergunta, você pode apenas cole isso diretamente na linha de comando):
sed 's#/>#/>\n#g' simple_file.xml |
perl -ne 'if(/row id=.(.+?)\".+name=.(.+?)\".+group_id=.(.+?)\"/){
push @{$k{join("\t",$2,$3)}},$1;}
END{
foreach (keys(%k)){
if($#{$k{$_}}>0){
print "$_\t",pop @{$k{$_}},"\n"
} }}'
EXPLICAÇÃO:
-
sed 's#/>#/>\n#g' simple_file.xml: Adicione uma nova linha após cada entrada (após cada/>) para facilitar a análise. -
perl -ne: processa o arquivo, linha por linha -
/row id= ... group_id=.(\d+)/;: use um regex (que geralmente é uma idéia ruim para arquivos HTML [X], você pode ter sangue de gatinhos fofos nas mãos) para obter asrow_id,nameegroup_id, elas são salvas como$1,$2e$3respectivamente. -
push @{$k{join("\t",$2,$3)}},$1;: isso é um pouco mais complexo. Ele cria um hash de matrizes chamadas (%k) e, em seguida, usajoinpara conectar osnameegroup_ida uma guia. Finalmente, adiciona orow_idao array. Em outras palavras, se seurow_idfor123, seunameserá456e seugroup_idserá789, isso criará um array e o salvará como o valor de hash%kpara chave %código%. -
O bloco
456 789é executado uma vez, quando o restante do arquivo é processado. Ele vai passar por cada uma das chaves do hash (cujos valores são matrizes) e imprimir esses casos em que a matriz tem mais de uma entrada, em outras palavras, as duplicatas. A funçãoEND{}retorna o último elemento de um array, neste caso opop.
Eu corri isto no seu exemplo e obtive esta saída:
4022 67581916031 306643757002
---- ---------- ------------
| | |---------------> row id
| |---------------------------> group id
|---------------------------------------> name
Se você não viu o link no segundo ponto, gostaria de enfatizar que você. Devemos. Nunca. Analise. [X] HTML Com. Regular. Expressões.