Ferramenta no unix para subtrair arquivos de texto?

16

Eu tenho um arquivo grande composto de campos de texto separados por ponto e vírgula na forma de uma tabela grande. Foi classificado. Eu tenho um arquivo menor composto dos mesmos campos de texto. Em algum momento, alguém concatenou esse arquivo com outros e fez uma classificação para formar o arquivo grande descrito acima. Eu gostaria de subtrair as linhas do arquivo pequeno do grande (ou seja, para cada linha no arquivo pequeno, se uma string correspondente existir no arquivo grande, exclua essa linha no arquivo grande).

O arquivo parece mais ou menos assim

GenericClass1; 1; 2; NA; 3; 4;
GenericClass1; 5; 6; NA; 7; 8;
GenericClass2; 1; 5; NA; 3; 8;
GenericClass2; 2; 6; NA; 4; 1;

etc

Existe uma maneira rápida e elegante de fazer isso ou eu tenho que usar o awk?

    
por Escher 29.09.2014 / 16:37

2 respostas

27

Você pode usar grep . Dê o arquivo pequeno como entrada e diga para encontrar linhas não correspondentes:

grep -vxFf file.txt bigfile.txt > newbigfile.txt

As opções usadas são:

   -F, --fixed-strings
          Interpret PATTERN as a  list  of  fixed  strings,  separated  by
          newlines,  any  of  which is to be matched.  (-F is specified by
          POSIX.)
   -f FILE, --file=FILE
          Obtain  patterns  from  FILE,  one  per  line.   The  empty file
          contains zero patterns, and therefore matches nothing.   (-f  is
          specified by POSIX.)

   -v, --invert-match
          Invert the sense of matching, to select non-matching lines.  (-v
          is specified by POSIX.)
   -x, --line-regexp
          Select only those matches that exactly match the whole line.  
          (-x is specified by POSIX.)
    
por 29.09.2014 / 16:42
17

comm é seu amigo:

NAME comm - compare two sorted files line by line

SYNOPSIS comm [OPTION]... FILE1 FILE2

DESCRIPTION Compare sorted files FILE1 and FILE2 line by line.

   With  no  options, produce three-column output.  Column one contains lines unique to FILE1, column two contains
   lines unique to FILE2, and column three contains lines common to both files.

   -1     suppress column 1 (lines unique to FILE1)

   -2     suppress column 2 (lines unique to FILE2)

   -3     suppress column 3 (lines that appear in both files)

( comm provavelmente terá um benefício de desempenho acima de grep , pois leva em conta a classificação).

Por exemplo:

comm -1 -3 file.txt bigfile.txt > newbigfile.txt
    
por 29.09.2014 / 17:11