como encontrar campo duplicado em mais de 100 arquivos

1

Eu tenho cerca de 120 arquivos, cada um com > 1000 linhas

Cada linha tem sua própria chave. As colunas são | separado

aqui está uma linha de exemplo, a coluna-chave (coluna 11 sempre coluna 11) é: 2010\ITE854075_RECardProtectionlogi.msg

Erro: nulo, dados:     | 862799 | 00318070L | EMA | EMAIL | null | 20100705 | 2010-07-05     14: 59: 39.0 | nulo | AUTO_20100705 | 2010 \ 07 \ 05 \ ITE854075_RECardProtectionlogi.msg | País     desconhecido

Existe uma maneira de encontrar todas as linhas que tenham valor de chave / coluna 11 (a linha inteira não corresponderá)? Posso fazer isso na linha de comando ou em um script? Eu usarei o cygwin.

Eu não tenho nem idéia de como começar, então mesmo que você sinta vontade de me dar os comandos adequados para procurar, isso será recebido com gratidão.

Cada linha tem a sua própria chave, pelo que existem potencialmente tantas chaves quantas as linhas.

Eu só quero que o script seja executado em um diretório inteiro e relate chaves duplicadas entre todos os arquivos, sem nenhuma outra entrada do usuário.

O que define uma chave é estar na coluna 11.

    
por WendyG 21.11.2018 / 17:00

2 respostas

0

Assumindo que por "chave" você quer dizer "coluna", você poderia usar algo assim:

cut -f 11 -d "|" $(find . -type f -iname "*.txt") | sort | uniq -d | sed 's/\/./g' | while read duplicate; do grep -rHn "|$duplicate|" * ; done

Você provavelmente terá que alterar o conteúdo do $(find -iname) para qualquer extensão dos seus arquivos de log (ou apenas removê-lo se os únicos arquivos no diretório forem arquivos de log. Isso localizará recursivamente todos os arquivos de log e os corresponderá.

A saída para alguns dados de teste é assim:

test_data.txt:1:Error: null, Data: |862799|00318070L|EMA|EMAIL|null|20100705|2010-07-05 14:59:39.0|null|AUTO_20100705|2010\ITE854075_RECardProtectionlogi.msg|Country not known test_data.txt:5:Error: null, Data: |862799|00318070L|EMA|EMAIL|null|20100705|2010-07-05 14:59:39.0|null|AUTO_20100705|2010\ITE854075_RECardProtectionlogi.msg|Country not known test_data_2.txt:2:Error: null, Data: |862799|00318070L|EMA|EMAIL|null|20100705|2010-07-05 14:59:39.0|null|AUTO_20100705|2010\ITE854075_RECardProtectionlogi.msgIDONTMATCH|Country not known test_data.txt:3:Error: null, Data: |862799|00318070L|EMA|EMAIL|null|20100705|2010-07-05 14:59:39.0|null|AUTO_20100705|2010\ITE854075_RECardProtectionlogi.msgIDONTMATCH|Country not known test_data_2.txt:4:Error: null, Data: |862799|00318070L|EMA|EMAIL|null|20100705|2010-07-05 14:59:39.0|null|AUTO_20100705|2010\ITE854075_RECardProtectionlogi.msgIlikecake|Country not known test_data.txt:7:Error: null, Data: |862799|00318070L|EMA|EMAIL|null|20100705|2010-07-05 14:59:39.0|null|AUTO_20100705|2010\ITE854075_RECardProtectionlogi.msgIlikecake|Country not known

Onde estão todas as linhas dentro dos arquivos com o campo 11 duplicado.

Explicação do que o comando faz.

cut -f 11 -d "|" Obtém o 11º campo (delimitado por |)

find . -type f -iname "*.txt" considere todos os arquivos terminados em .txt no diretório atual (recursivamente)

sort | uniq -d mostra todos os "campos 11s" duplicados

sed /\/./g' Isso é um hack porque \ estraga o bash. Nós o substituímos por . , que grep corresponde a qualquer caractere.

while read duplicate; do grep -rHn "|$duplicate|" *; done - iterar sobre a lista de duplicatas e localizar todas as ocorrências delas, gerando o nome do arquivo e os números de linha de onde ocorreram duplicatas.

    
por 21.11.2018 / 18:18
0

Não está claro o que você está tentando fazer, mas vou tentar:

Primeiro, qual é a sua linha? Você deu isso como uma linha:

Error: null, Data:|862799|00318070L|EMA|EMAIL|null|20100705|2010-07-05 14:59:39.0|null|AUTO_20100705|2011\ITE854075_RECardProtectionlogi.msg|Country not known

Se suas linhas se parecem com isso, então, sua chave está no campo 11

2011\ITE854075_RECardProtectionlogi.msg

mas, o que define sua chave? É só estar no campo 11?

Se for assim, você pode fazer algo assim, no diretório com seus arquivos de destino:

sort --field-separator='|' --key=11 <(\grep --recursive --line-number --color=always --with-filename '' *)

isto lhe dará uma saída colorida do nome do arquivo, seguido pelo número da linha naquele arquivo, e então a própria linha, toda ordenada pelo campo-chave 11; então, na saída, todas as chaves correspondentes em qualquer arquivo, aparecem uma em cima da outra ...

Acho que isso te dará uma pista, pelo menos

Observação : a barra invertida na frente de grep é para evitar aliases grep .

    
por 21.11.2018 / 18:29