Divide o arquivo comparando dois campos nos arquivos

0

Tem dois arquivos que precisam comparar as duas primeiras colunas.

Exemplo de arquivo de entrada1:

|CID|SID|order|orderdate|confirmdate
|151244127820|7177638911583| 2|2015-02-04 07:14:44|2015-02-04 07:15:32
|151244127820|7177638922976| 4|2015-02-04 07:16:19|2015-02-04 07:19:47
|151244127824|7177638920385| 2|2015-02-04 07:14:22|2015-02-04 07:18:48
|151244127824|7177638924073| 3|2015-02-04 07:18:40|2015-02-04 07:20:11
|151244127825|7177638921040| 1|2015-02-04 07:12:58|2015-02-04 07:19:02
|151244127827|7177638917056| 2|2015-02-04 07:14:17|2015-02-04 07:17:31
|151244127827|7177638968972| 3|2015-02-04 07:17:36|2015-02-04 07:36:22

arquivo de entrada2:

|cID|SID|order|orderdate|confirmdate
|151244127820|7177638911583|   2|2015-02-04 07:14:44|2015-02-04 07:15:32
|151244127820|7177638922976|   4|2015-02-04 07:16:19|2015-02-04 07:19:47
|151244127834|7177638920385|   2|2015-02-04 07:14:22|2015-02-04 07:18:48
|151244127834|7177638924073|   3|2015-02-04 07:18:40|2015-02-04 07:20:11
|151244126585|7177638921040|   1|2015-02-04 07:12:58|2015-02-04 07:19:02
|151244126585|7177638917056|   2|2015-02-04 07:14:17|2015-02-04 07:17:31
|151244127827|7177638968970|   3|2015-02-04 07:17:36|2015-02-04 07:36:22

Se o CID no arquivo de entrada2 não for encontrado no arquivo1, escreva a linha completa em um novo arquivo. E se o CID no arquivo de entrada2 for encontrado no arquivo1, mas o SID não for encontrado, escreva a linha completa em um novo arquivo.

    
por user_tmo 15.02.2015 / 09:10

3 respostas

2
awk -F'|' 'FNR==NR{a[$2]=$2;b[$3]=$3;next};{if($2 in a){print $0 > "new_file_1"};if(($2 in a )&& !($3 in b)){print $0 > "new_file_2"}} file1 file2

detalhes ...

{if($2 in a){print $0 > "new_file_1"} : if SID in file2  matches SID in file1 redirect to a file called new_file_1

..

if(($2 in a )&& !($3 in b)){print $0 > "new_file_2"} :if SID in file2 matches SID in file1 but CIDs does not match, redirect to a file called new_file_2
    
por 15.02.2015 / 10:25
1
awk -F'|' '
FNR==NR{
    cid[$2]=1
    sid[$3]=1
    next
    }
{
    if (!($2 in cid))
        print
    else
        if (!($3 in sid))
            print
    }' file1 file2

Breve explicação:

Crie dois arrays exclusivos ( cid e sid values) do primeiro arquivo.

Em comparação com o segundo e terceiro campos (o primeiro campo é contado a partir do início da linha até o primeiro delimitador, portanto, está vazio) de cada linha do segundo arquivo e, de acordo com os termos, a linha de impressão.

    
por 15.02.2015 / 10:05
0

Acho que isso é o que você quer:

for n in 3 0
do  nl -w1 -s."$n" <&"$n"
done 3<file1 <file2      |
sort -t\| -unk2,2 -nk3,3 |
sort -t\| -nk1,1         |
grep '^[^|]*0|'

... nos meus testes impressos ...

4.0|151244127834|7177638920385|   2|2015-02-04 07:14:22|2015-02-04 07:18:48
5.0|151244127834|7177638924073|   3|2015-02-04 07:18:40|2015-02-04 07:20:11
6.0|151244126585|7177638921040|   1|2015-02-04 07:12:58|2015-02-04 07:19:02
7.0|151244126585|7177638917056|   2|2015-02-04 07:14:17|2015-02-04 07:17:31
8.0|151244127827|7177638968970|   3|2015-02-04 07:17:36|2015-02-04 07:36:22

E olhe - não é apenas muito simples (e provavelmente muito rápido, mesmo para entradas muito grandes) - mas você até consegue manter os números de linha. Mas se você não quiser, basta anexar ...

... | cut -d\| -f2-

... até a cauda do duto.

    
por 16.02.2015 / 08:04