lista de padrão a ser removido do arquivo

0

Para ilustrar mais, temos dois conteúdos de arquivo:

arquivo1

hello
1_hello 
2_hello
world
1_world
2_world
hello1
1_hello1
2_hello1
world1
1_world1
2_world1

arquivo2

This
hello
1_hello
2_hello
is world
1_world
2_world
my
hello1
1_hello1
2_hello1
word
world1
1_world1
2_world1
file 

o que eu quero é iterar a primeira coluna do arquivo1 e remover as entradas que estão combinando no arquivo2 e produzir a saída como:

This
is
my 
word
file

Como posso proceder?

    
por ASAD 20.09.2017 / 16:17

5 respostas

5

Você quer usar o awk para ler o arquivo1 e lembrar de todas as palavras. Em seguida, leia o arquivo2 e imprima as palavras que não foram vistas no arquivo1:

gawk -v RS='[[:space:]]+' 'NR==FNR {words[$1]=1; next} !($1 in words)' file1 file2

Isso usa qualquer sequência de espaço em branco como separador de registro, então cada palavra é tratada como uma "linha" separada. Este agora GNU awk específico, mas esse é o awk padrão no Ubuntu

    
por glenn jackman 20.09.2017 / 18:10
3

Você pode usar grep -f FILE para obter padrões de um arquivo FILE . No seu caso, eu recomendo alguns sinalizadores adicionais (veja a explicação abaixo) para a seguinte invocação grep final:

grep -v -x -F -f file1 -- file2
  • -f FILE - Obtenha padrões de FILE , um por linha.

  • -F - Interprete o padrão como uma lista de sequências fixas, separadas por novas linhas, sendo que qualquer uma delas deve ser correspondida.

  • -x - Selecione apenas as correspondências que correspondem exatamente à linha inteira. (Você pode querer remover essa opção se quiser permitir linhas parcialmente correspondentes).

  • -v - Inverte o sentido da correspondência para selecionar linhas não correspondentes.

Fonte: a documentação do GNU grep ou, alternativamente, < a href="http://manpages.ubuntu.com/manpages/xenial/en/man1/grep.1.html"> página de manual

Todas as opções usadas acima são especificadas pelo POSIX e não requerem extensões GNU.

    
por David Foerster 02.10.2017 / 12:18
1

Esta linha de comando deve fazer o truque:

while read -r word; do sed -e "s/\<$word\>//g" -e '/^\s*$/d' file2 -i; done < file1

Após a execução do comando acima, o arquivo de saída - file2 - deve ficar assim:

This
is
my
word
file

Versão mais legível da linha de comando acima:

while read -r word; do \
    sed -e "s/\<$word\>//g" -e '/^\s*$/d' file2 -i; \
done < file1

O loop while lê o arquivo linha por linha - < file1 . O valor de cada linha é usado como um valor da variável criada temporária, chamada $word - -r word . Essa variável é usada como um argumento no comando sed e é substituída por [ s ] por um valor em branco em file2 , a primeira expressão: "s/\<$word\>//g" = s/<source_value>/<replacement_value>/g . A g flag significa - aplica a substituição a todas as correspondências. Então, se houver uma linha em branco no arquivo, ela será removida - a segunda expressão: '/^\s*$/d' .

Precisamos usar a sintaxe \<...\> para encontrar apenas as correspondências exatas. Precisamos de aspas duplas - "..." - para a primeira expressão porque $word é o nome da variável e queremos expandi-la como seu valor dentro do comando sed .

A opção -i significa que as alterações serão feitas em seus lugares dentro do arquivo de destino - file2 . Se esta opção for removida, o resultado será lançado para stdout, mas não será significativo. A opção -i.bak não é aplicável a este cenário, porque o arquivo de destino será sobrescrito várias vezes, portanto, você deve criar uma cópia de backup antecipadamente.

    
por pa4080 20.09.2017 / 17:22
0

Use grep com o sinalizador -v (invert).

Com o uso da regex estendida ( -E ), você pode criar uma lista de padrões separados por | , que você deseja excluir, por exemplo, pattern1|pattern2|pattern3 :

grep -v -E "^[0-9]|world|hello" file
    
por RoVo 20.09.2017 / 16:26
0

Embora o critério de remoção não seja muito claro, presumo que as partes a serem removidas são ( www\n1_www\n2_www ) para todas as palavras www (corrija-me se estiver errado)

Usando (gnu) sed:

sed -zr 's/(\w+)\n1_\n2_\n//g' ex
    
por JJoao 20.09.2017 / 16:43