Como remover linhas idênticas em um arquivo de outro, usando sed?

4

Eu tenho dois arquivos, sendo um deles um superconjunto do outro. Eu quero remover as linhas idênticas nos arquivos menores do arquivo maior.

Uma possível complicação é que as linhas contêm barras invertidas.

Como faço isso?

    
por paradroid 20.06.2011 / 11:05

3 respostas

8

Aqui está meu snippet:

remove_lines()
{
    # remove lines from a file 
    #  
    # $1 - source file with patterns of lines to be removed
    # $2 - destination file
    tmpfile=$(mktemp "$(dirname -- "$2")"/XXXXXXXX) &&
    grep -F -f "$1" -v -- "$2" >>"$tmpfile" &&
    mv -- "$tmpfile" "$2" &&
}

EDIT: Acabei de perceber que não há sed , mas isso não foi crítico, foi?

    
por 20.06.2011 / 11:18
2

Experimente o seguinte script:

## $1 - Small File
## $2 - Large File

sed 's/^/\//; s/$/\/d/; s/\/\\/g' $1 > $HOME/sed_scpt.txt
sed 's/\/\\/g' $2 | sed -f $HOME/sed_scpt.txt > $HOME/desired_output.txt

## Alternatively, you could change the 2nd line with the following;
sed -f $HOME/sed_scpt.txt $2 > $HOME/desired_output.txt

Espero que isso ajude.

NOTA: Eu usei o GNU sed 4.2.1, se isso também importa.

    
por 03.07.2011 / 10:25
2

A resposta de @rajish usando grep foi aproximada, mas ignorou algo: a pergunta sobre a remoção de linhas idênticas. Por padrão, grep corresponderá a strings (partes de linhas).

POSIX grep tem uma opção adequada:

-x
Consider only input lines that use all characters in the line excluding the terminating newline to match an entire fixed string or regular expression to be matching lines.

Dado que, pode-se usar grep para fazer isso:

cp -f -p input.txt input.txt~
grep -v -x -F -f input.pat input.txt~ >input.txt

onde input.pat contém as linhas a serem removidas, e input.txt é o arquivo a ser atualizado.

A solução de @nvarun usando sed teve um problema semelhante, além de não escapar de / caracteres no arquivo padrão. Este exemplo funciona para mim e limita a sintaxe a POSIX sed :

cp -f -p input.txt input.txt~
sed -e 's/\([\/]\)/\/g' -e 's/^/\/^/' -e 's/$/$\/d/' input.pat > input.sed
sed -f input.sed input.txt~ >input.txt

Apenas para ser arrumado, salve o arquivo original antes de atualizá-lo ( POSIX cp ) .

input.pat

first
this is second
second/third
second\third

input.txt

first
only first should match
this is not first
this is second
the previous line said this is second
first/second/third
second/third
first\second\third
second\third

Resultado:

only first should match
this is not first
the previous line said this is second
first/second/third
first\second\third
    
por 15.02.2016 / 18:10