diffrence entre dois arquivos de números de linhas diferentes

1

Ontem eu perguntei esta questão , e recebi respostas incríveis, é realmente uma alegria para fazer perguntas neste site.

Hoje recebi uma pergunta um pouco diferente

diga que tenho csv1

1,2,3,4
5,6,7,8 --
9,10,11,12
13,14,15 --

e csv2 tem

1,2,3,4,5 --
20,21,22,23,24
24,25,26,27,28
9,10,11,12,30 --
45,46,47,48,60

Como posso imprimir apenas as linhas cujos primeiros 4 campos estão presentes apenas em um dos dois arquivos? Em outras palavras, descarte todas as linhas de cada arquivo cujos primeiros quatro campos também estão presentes em uma linha no outro arquivo.

1,2,3,4
9,10,11,12
20,21,22,23,24
24,25,26,27,28
45,46,47,48,60

Observe que -- não existe nos arquivos reais , adicionei-os para ajudar você a perceber a diferença.

Até agora, estou carregando tudo em matrizes numpy e comparando cada elemento

if a[i] == b[i] and ...

Mas eu quero saber se há uma maneira melhor de fazer isso usando as ferramentas do Linux.

Editar

Cada linha no csv2 tem uma linha correspondente no csv1 e não há linhas duplicadas no mesmo arquivo. basicamente eu estou tentando remover csv2 de csv1 e produzir o resto de csv1.

    
por Lynob 25.06.2015 / 00:43

1 resposta

3

Aqui está uma maneira:

$ awk -F, 'NR==FNR{a[]++; next}!a[]' csv2 csv1
110,12,31,345
1,12,14,55 
12,53,22,10
1,12,32,44 

Explicação

  • -F, : define o separador de campos para,. Agora, o primeiro campo separado por vírgula de cada linha será , o segundo e assim por diante.
  • NR==FNR : estas são duas variáveis especiais do awk. NR é a linha de entrada atual e FNR é o número da linha do arquivo atual. Os dois serão iguais apenas enquanto o primeiro arquivo estiver sendo lido.
  • NR==FNR{a[]++; next} : durante a leitura do primeiro arquivo, salve os primeiros 4 campos como uma chave na matriz a e defina seu valor como 1. Isso basicamente salva todos os 4 primeiros campos de csv1 . O next garante que pulemos imediatamente para a próxima linha e não processemos o restante do script.
  • !a[] : a ação padrão do awk é imprimir a linha atual. Então, se você usar algo que seja verdadeiro, o awk entende que deve imprimir essa linha. !a[ ] é verdadeiro quando a[] não define o que acontecerá para as linhas em csv1 cujos primeiros 4 campos não estavam presentes em nenhuma linha de csv2 . Portanto, esta diretiva fará com que todas as linhas cujos primeiros 4 campos nunca tenham sido vistos (para que seu valor na matriz a não seja 1) sejam impressas.
por terdon 25.06.2015 / 01:15