Classificando colunas de dois arquivos com awk

2

Eu tenho dois arquivos de entrada

28a39a289906c01159f999a68996091a [email protected]
274d1d2c7e931fb55ac0c91dd41f2be7 [email protected]
44d25d3b1b70b240d5058f1be1cef576 [email protected]
2227a768f6d253b7bf81bb4ecb15b52d [email protected]

e

28a39a289906c01159f999a68996091a
274d1d2c7e931fb55ac0c91dd41f2be7
44d25d3b1b70b240d5058f1be1cef576
2227a768f6d253b7bf81bb4ecb15b52d

Estou tentando excluir todas as linhas no arquivo 1, em que arquivo2 e arquivo1 têm uma coluna correspondente 1.

supressão de md5.

O que eu encontrei foi awk 'NR==FNR{a[$1]=$0;next}{print a[$2]}' $1 $2

que eu sei que é muito próximo, não tenho certeza do que fiz antes para fazer o que eu quero fazer agora.

    
por Arian 24.02.2012 / 23:38

3 respostas

3

Se a ordem não importa (ou seja, apenas exclua todos os emails com um md5 no arquivo de exclusão) e você não está casado com o awk, use join :

join -v 1 -j 1 <(sort emails) <(sort excludes)

-v 1 diz para imprimir linhas no primeiro arquivo (e-mails) que não têm uma linha correspondente no segundo arquivo (exclui).
-j 1 diz para ver apenas a primeira coluna de cada.

Se você quiser usar o awk, acredito que isso funcione:

awk 'NF==1{exclude[$1]++} NF==2&&!exclude[$1]' excludes emails

Ou se os dois arquivos corresponderem linha por linha e você só quiser excluir, por exemplo, linha 2 se ambos tiverem o mesmo hash nessa linha em particular, use isto:

awk 'NF==1{hash[FNR]=$1} NF==2&&hash[FNR]!=$1' excludes emails
    
por 25.02.2012 / 03:56
2

Isso tem o benefício de os arquivos poderem ser feitos em qualquer ordem:

sort file1 file2 | uniq -u --check-chars 32 | grep -E '.{33}'

sort file1 file2 está combinando e classificando os arquivos em preparação para o uniq.

uniq -u --check-chars 32 considera apenas os primeiros 32 caracteres e, com -u , imprime apenas as linhas exclusivas.

grep -E '.{33}' imprime apenas as linhas que contêm 33 ou mais caracteres.

EDITAR

Como Peter.O aponta, isso não atende o caso em que duas ou mais entradas na lista de arquivos têm o mesmo md5. Nesse caso, esses arquivos não serão impressos. Eu gosto da solução join da melhor.

No entanto, essa lógica depende de todos os arquivos separados terem md5's únicos , o que é uma suposição ruim, dependendo do uso dessa saída. Aqui está um exemplo de um script de backup usando a lógica md5sum. Embora a lógica join identifique corretamente fileA e fileB (diferentemente da minha solução), ainda há um problema:

echo "hello world" > fileA
cp fileA fileB
./backup_script.sh
cp fileA fileC
./backup_script.sh

O backup do arquivo indC foi feito?

    
por 25.02.2012 / 03:57
1

Este comando deve funcionar:

awk '
  NR==FNR {
    a[$1]=$0;
    next
  }
  { if ( a[$1] ) delete a[$1] } 
  END { 
    for ( md5 in a ) { 
      if ( a[md5] ) { print a[md5] } 
    } 
  }
' file1 file2
    
por 24.02.2012 / 23:57