Apagar linhas de um arquivo se elas contiverem um regex de conteúdo em outro arquivo

1

Eu tenho um arquivo grande (150K + linhas) contendo registros DNS, chamarei esse arquivo. Eu tenho um arquivo menor contendo certos nomes, FileB. Eu quero excluir todas as linhas no FileA que terminam com o que está no FileB. Mas eu não quero excluir a linha se o nome aparecer no começo do registro.

Eu sei como usar grep -v name$ para remover manualmente os nomes que aparecem no final do registro, mas preciso de um loop para percorrer todo o arquivo B. Até agora, minhas tentativas falharam.

Aqui está um exemplo que espero ilustrar o que eu procuro:

FileA:
hosta IN A 10.20.30.40
hostb IN A 20.30.40.50
myurl IN CNAME hostb
yours IN CNAME hostb

Se FileB contiver hostb, somente as últimas duas linhas serão excluídas; as duas primeiras linhas são deixadas como estão.

    
por Piotr 29.06.2017 / 09:34

3 respostas

1

Você pode usar o sinalizador -f para grep para todas as linhas no Arquivo B:

grep -v -f FileB FileA

Isso é quase o que você quer. Mas isso remove também as linhas em que os padrões de FileB não são no final, e você declarou explicitamente que só deve corresponder quando estiver no final. Portanto, precisamos modificar FileB de acordo. Podemos usar sed para adicionar o regex ao final da linha, que é o sinal $ :

sed 's/$/$/' FileB

Parece que não está substituindo nada, mas na verdade está adicionando um $ em cada final de linha.

Agora podemos usar a substituição de processo para juntar tudo isso:

grep -v -f <(sed 's/$/$/' FileB) FileA
    
por 29.06.2017 / 09:52
0

Para fazer o loop de todo o arquivo B, você pode usar a abordagem como:

for i in 'cat FileB'
do
<do your work>
done

Mas talvez seja melhor filtrar também pelo CNAME

    
por 29.06.2017 / 09:52
0

Com sed você pode fazer assim:

sed -n '/^[^ ]*$/{H;d;};G;/ \(.*\)\n.*\n/d;P' fileB fileA

Isto é: Primeiro processo fileB. Se as linhas não contiverem espaços, elas devem ser nomes de host no arquivo B e nós as adicionamos ao espaço de espera e continuamos ( {H;d;} )

Todas as outras linhas devem ser do fileA. Anexando o espaço de espera com a lista de nomes de host ( G ), todas as linhas com a última palavra da linha que são repetidas na lista de nomes de host podem ser excluídas. As linhas restantes são impressas sem a lista final ( P ). A opção -n suprime a saída padrão.

Editar: Na verdade, deve-se fazer

sed -n '/^[^ ]*$/{H;d;};G;/ \(.*\)\n.*\n\n/d;/ \(.*\)\n.*\n$/d;P' fileB fileA

para evitar casos especiais.

    
por 29.06.2017 / 09:56