Encontre nomes de arquivos duplicados com padrão de correspondência específico

1

Eu tenho uma pasta com alguns arquivos (trecho do conteúdo da pasta)

PAT1.URGRSVP.50.WR786842JOB11632.WRS20140.FILE0005.DAT
PAT1.URGRSVP.50.WR786842JOB11643.WRS20140.FILE0003.DAT
PAT1.URGRSVP.51.WR786842JOB11643.WRS29232.FILE0003.DAT
PAT1.URGRSVP.50.WR786842JOB11694.WRS20140.FILE0002.DAT
...
...
...

Meu foco está nos blocos 3 (50,50,51,50) e 5 (WRS20140, WRS20140, WRS29232, WRS20140). Como posso escrever um script que exibe os nomes de arquivos duplicados com o mesmo bloco 3 e 5 (as duplicatas da combinação das cadeias de bloco 3 e 5)?

Assim, a saída deve listar o seguinte no exemplo acima

PAT1.URGRSVP.50.WR786842JOB11643.WRS20140.FILE0003.DAT
PAT1.URGRSVP.50.WR786842JOB11694.WRS20140.FILE0002.DAT
    
por user6123723 03.02.2014 / 07:12

2 respostas

3
ls *.DAT | awk -F. '{ if (c[$3$5]) print $0 ; c[$3$5]=$0}'

Acima, o awk analisa cada nome de arquivo usando . como um separador de campo. Se tiver visto a combinação do terceiro e quinto campos antes, imprime o nome do arquivo. Com seus nomes de arquivo como entrada, o acima produz:

PAT1.URGRSVP.50.WR786842JOB11643.WRS20140.FILE0003.DAT
PAT1.URGRSVP.50.WR786842JOB11694.WRS20140.FILE0002.DAT

MORE: Vamos examinar os comandos awk em mais detalhes:

if (c[$3$5]) print $0 ; c[$3$5]=$0

O acima consiste em duas declarações: uma declaração "if" e uma atribuição. A declaração "if" é:

if (c[$3$5]) print $0

Nesta declaração, c é uma "matriz associativa". Isto significa que você lhe dá uma chave e lhe devolve um valor. Estamos usando $3$5 como a chave em que $3 é o terceiro "bloco" (o que o awk chamaria de terceiro "campo") e $5 é o quinto bloco. Se essa chave foi anteriormente não atribuída, então c[$3$5] retornará um valor vazio (falso). Portanto, se essa combinação de terceiro e quinto blocos foi vista antes, então print $0 é executado, o que significa que todo o nome do arquivo é impresso. Caso contrário, a instrução de impressão é ignorada.

A segunda afirmação é:

c[$3$5]=$0

Isso atribui o nome do arquivo ( $0 ) ao array associativo sob a chave do terceiro e quinto campos: $3$5 . Assim, na próxima vez que esses campos forem vistos na instrução "if", a instrução print será executada.

    
por 03.02.2014 / 07:26
1

Veja como você pode fazê-lo com awk : use uma variável para contar o número de vezes que viu o mesmo par de terceiro e quinto campo e imprima o nome do arquivo se já viu esse par em particular .

Com esses nomes de arquivo em um arquivo chamado entrada, isso seria parecido com:

$ awk -F. '{if (dups[$3$5]++) print $0}' input

Se os nomes dos seus arquivos puderem conter espaços em branco ou outros caracteres interessantes, use find em vez de ls para listá-los, com algo como:

$ find . -name 'PAT1.*.DAT' -print0 | \
    awk -F. 'BEGIN{RS="
$ awk -F. '{if (dups[$3$5]++) print $0}' input
"} {if (dups[$3$5]++) print $0}'

Como benefício secundário, você pode inspecionar a variável dups em um bloco END para imprimir quantos de cada par você viu na entrada.

    
por 03.02.2014 / 07:27