Compare o arquivo similar e não os arquivos similares exibidos abaixo da saída no awk?

2

Gostaria de comparar os dois arquivos a seguir e exibir uma comparação dos dois arquivos entre si.

Arquivo nº 1:

DATE       DS 
2012-08-02 1
2013-06-23 1
2013-06-27 2
2013-06-28 2
2013-06-29 779

Arquivo nº 2:

DATE       DE
2013-06-16 5
2013-06-17 1
2013-06-18 3
2013-06-19 1
2013-06-20 5
2013-06-21 6
2013-06-22 6
2013-06-23 6
2013-06-24 5
2013-06-25 9
2013-06-26 7
2013-06-27 22
2013-06-28 59
2013-06-29 334
2013-06-30 11

Comparação do arquivo # 1 & # 2:

DATE       DS   DE 
2012-08-02 -    1
2012-08-05 -    2
2013-06-16 5    -  
2013-06-17 1    -  
2013-06-18 3    -  
2013-06-19 1    -  
2013-06-20 5    -  
2013-06-21 6    -
2013-06-22 6    -
2013-06-23 6    -
2013-06-24 5    -
2013-06-25 9    -
2013-06-26 7    1
2013-06-27 22   2
2013-06-28 59   2
2013-06-29 334  779
2013-06-30 11   -

Acima de file1, DATE e DS significa "dados selecionados" para uma data específica de quantos selecionados. Está mostrando do arquivo1 e arquivo2 também o mesmo, mas datas diferentes para quantos "desativado" (DE).

Agora quero exibir o arquivo1 & file2 usando o AWK.

Data para $ 1 nos dois arquivos, $ 2 no arquivo1, $ 2 no arquivo2. Se uma data específica for comparada, ela também exibirá DE, DA.

Por exemplo:

DATE      DE DS
2012-08-1 -   1 # Date is present in $1 from file1 but file2 is not there. 
                # This is the date I want. Also I want to display a (-) for 
                # DE which is not there.
    
por ganik 17.07.2013 / 22:04

1 resposta

3

Talvez:

join -a 1 -a 2 -o 0,1.2,2.2 -e - file1 file2

Descrição do comando acima

Se em um sistema GNU (como a maioria das distribuições baseadas em Linux), você pode descobrir as opções para join com este comando:

$ info coreutils 'join invocation'

ou

$ info join

(assumindo que o diretório info seja mantido adequadamente)

Ou você pode verificar a especificação POSIX para ver o que funciona com segurança nos Unices.

As opções acima são as seguintes:

'-a FILE-NUMBER'
     Print a line for each unpairable line in file FILE-NUMBER (either
     '1' or '2'), in addition to the normal output.

Isso abrange sua necessidade de linhas não emparelhadas (onde a data (o campo de junção) não aparece em ambas) a serem incluídas.

'-o FIELD-LIST'
     Construct each output line according to the format in FIELD-LIST.
     Each element in FIELD-LIST is either the single character '0' or
     has the form M.N where the file number, M, is '1' or '2' and N is
     a positive field number.

Esta opção constrói o formato que será exibido para cada linha de saída de join . Um 0 emite o campo que está sendo correspondido entre os dois arquivos. Esta é a data. O 1.2 é a segunda coluna do primeiro arquivo (arquivo1) e o 2.2 é a segunda coluna do segundo arquivo (arquivo2).

'-e STRING'
     Replace those output fields that are missing in the input with
     STRING.

Esta opção especifica qual caractere deve ser usado para os campos que estão faltando no arquivo1 ou no arquivo2. Isso é o que gera o - na saída final.

Usando a coluna

Ao utilizar a sugestão do @ GlennJackman, você pode limpar ainda mais a saída para que ela seja formatada em colunas de tamanhos iguais:

$ join -a 1 -a 2 -o 0,1.2,2.2 -e - file1 file2 | column -t
DATE        DS   DE
2012-08-02  1    -
2013-06-16  -    5
2013-06-17  -    1
2013-06-18  -    3
2013-06-19  -    1
2013-06-20  -    5
2013-06-21  -    6
2013-06-22  -    6
2013-06-23  1    6
2013-06-24  -    5
2013-06-25  -    9
2013-06-26  -    7
2013-06-27  2    22
2013-06-28  2    59
2013-06-29  779  334
2013-06-30  -    11

Observe que os arquivos de entrada devem ser classificados na chave de junção (por padrão, o primeiro campo). Acima, não é porque na maioria dos locais "DATE" classifica após "2013". Portanto, não é garantido que funcione em todas as implementações join .

Você pode pular a primeira linha com ( ksh93 / zsh / bash syntax):

join -a 1 -a 2 -o 0,1.2,2.2 -e - <(tail -n +2 file1) <(tail -n +2 file2)
    
por 17.07.2013 / 22:20

Tags