Como remover linhas de um arquivo de texto que possui valor específico em uma coluna por meio de um arquivo de entrada?

0

Eu tenho um arquivo delimitado por pipe como abaixo.

data.txt

ESP|041336|46566|NY|CA
ESP|041337|46566|NY|CA
ESP|041338|46566|NY|CA
ESP|041339|46566|NY|CA
ESP|041340|46566|NY|CA
ESP|041341|46566|NY|CA

Eu tenho outro arquivo com valores na segunda coluna que precisa ser removido.

Input.txt

041337
041338
041339

Estou tentando remover linhas que possuem valores de input.txt em sua segunda coluna.

Resultado esperado

ESP|041336|46566|NY|CA
ESP|041340|46566|NY|CA
ESP|041341|46566|NY|CA

Estou tentando usar o grep aqui como abaixo para conseguir isso.

grep -vfw input.txt data.txt > output.txt

Isso não remove as colunas, mas gera um erro Nenhum arquivo ou diretório e retorna um arquivo vazio.

    
por Bala.C 04.09.2018 / 00:19

3 respostas

2

Se você quiser limitar a comparação ao segundo campo delimitado apenas, então você pode usar o awk em vez do grep:

$ awk -F'|' 'NR==FNR {a[$1]++; next} !($2 in a)' input.txt data.txt > output.txt

$ cat output.txt
ESP|041336|46566|NY|CA
ESP|041340|46566|NY|CA
ESP|041341|46566|NY|CA
    
por 04.09.2018 / 00:28
2

A opção -f espera um nome de arquivo. A maneira como você escreve, o nome do arquivo é o texto que segue o f , em -vfw , em outras palavras, é w .

Você tem que colocar uma opção que leva um argumento no final (exceto por tar , que usa uma análise de opção estranha).

Qualquer um deles deve funcionar.

grep -v -w -f input.txt data.txt > output.txt
grep -vwf input.txt data.txt > output.txt
grep -vwfinput.txt data.txt > output.txt

Observação: a mensagem de erro exata, que você deve sempre citar por completo quando faz uma pergunta, menciona o nome w .

grep: w : nenhum arquivo ou diretório desse tipo

    
por 04.09.2018 / 00:24
1
sed -nE '
   /\|/!{H;1h;d;}
   G
   /^[^|]+\|([^|]+)\|.*\n(\n|$)/!P
'  input.txt data.txt

Resultado:

ESP|041336|46566|NY|CA
ESP|041340|46566|NY|CA
ESP|041341|46566|NY|CA

Comentários:

  • Armazena as linhas input.txt no espaço de armazenamento em virtude de não haver um pipe nele. %código% Essas linhas são separadas por novas linhas no espaço de espera.

  • Para as linhas de dados, anexamos a área de espera ao espaço de padrões e tentamos procurar o segundo campo delimitado por tubos. Se não houver uma para ser encontrada, imprima a parte antes da primeira nova linha no espaço de padrão /\|/! .

    A regex, P corresponde ao espaço do padrão se o segundo campo /^[^|]+\|([^|]+)\|.*\n(\n|$)/ -delimited na linha de dados (de | ) corresponde a uma das strings de entrada, que estão no final do espaço padrão, delimitado por novas linhas. Ele tem uma condição OR no final, para cuidar do cenário quando o padrão correspondente era a última linha do arquivo data.txt .

Assume uma versão do GNU sed com regexps estendidos ativados para reduzir o ruído da linha.

    
por 04.09.2018 / 05:38