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
,name
egroup_id
, elas são salvas como$1
,$2
e$3
respectivamente. -
push @{$k{join("\t",$2,$3)}},$1;
: isso é um pouco mais complexo. Ele cria um hash de matrizes chamadas (%k
) e, em seguida, usajoin
para conectar osname
egroup_id
a uma guia. Finalmente, adiciona orow_id
ao array. Em outras palavras, se seurow_id
for123
, seuname
será456
e seugroup_id
será789
, isso criará um array e o salvará como o valor de hash%k
para 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.