Linhas comuns entre dois arquivos [duplicados]

2

Eu tenho o seguinte código que eu executo no meu terminal.

LC_ALL=C && grep -F -f  genename2.txt hg38.hgnc.bed > hg38.hgnc.goi.bed

Isso não me dá as linhas comuns entre os dois arquivos. O que estou perdendo ai?

    
por Marwah Soliman 14.10.2017 / 20:46

2 respostas

8

Use comm -12 file1 file2 para obter linhas comuns nos dois arquivos.

Você também pode precisar que seu arquivo seja classificado como comm para funcionar como esperado.

comm -12 <(sort file1) <(sort file2)

Em man comm :

-1     suppress column 1 (lines unique to FILE1)
-2     suppress column 2 (lines unique to FILE2)

Ou usando o comando grep você precisa adicionar a opção -x para corresponder à linha inteira como um padrão correspondente. A opção F informa a grep que corresponde ao padrão como uma string que não é uma correspondência de expressão regular.

grep -Fxf file1 file2

Ou usando awk .

awk 'NR==FNR{seen[$0]=1; next} seen[$0]' file1 file2

Isto está lendo toda a linha de arquivo1 em uma matriz chamada seen com a chave como linha inteira (em awk o $0 representa toda a linha atual).

Usamos NR==FNR como condição para executar seu bloco seguido apenas para a primeira entrada fle1 não arquivo2 , porque NR em awk se refere ao processamento atual número da linha e FNR estão se referindo ao número da linha atual em todas as entradas . então NR é exclusivo para cada arquivo de entrada, mas FNR é exclusivo para todas as entradas.

O next está informando que awk não continua o código de descanso e começa novamente até NR não ser igual a FNR , o que significa que todas as linhas de arquivo1 são lidas por awk .

Em seguida, o próximo seen[$0] será executado apenas para o segundo arquivo2 e para cada linha em arquivo2 irá procurar na matriz e imprimirá a linha onde ela existir no array .

Outra opção simples é usar sort e uniq :

sort file1 file2|uniq -d

Isso imprimirá os dois arquivos classificados, então uniq -d imprimirá apenas as linhas duplicadas. MAS isso é concedido quando NÃO há linhas duplicadas em ambos os arquivos, senão sempre é concedido mesmo que haja linhas duplicadas nos dois arquivos.

uniq -d <(sort <(sort -u file1) <(sort -u file2))
    
por 14.10.2017 / 20:50
2

Como você está rodando no Linux, eu suponho que seja GNU / Linux e você está usando o comando GNU diff .

Se você estiver executando o comando GNU diff , veja como todas as linhas alteradas e linhas comuns:

diff \
--old-line-format='-%l
' \
--new-line-format='+%l
' \
--unchanged-line-format=' %l
' \
"$@"

Isso é semelhante à saída diff clássica, mas não aparecem nomes de arquivos ou linhas separadoras na saída, e linhas antigas são marcadas com - , novas linhas são prefixadas com + e linhas comuns são prefixadas com um espaço .

Aqui está um script de exemplo e a saída resultante nos arquivos de teste:

$ cat diffcomm.sh
#!/bin/sh
diff \
--old-line-format='-%l
' \
--new-line-format='+%l
' \
--unchanged-line-format=' %l
' \
"$@"
$ cat > filea
a
b
c
d
$ cat > fileb
a
z
d
$ ./diffcomm.sh  filea fileb
 a
-b
-c
+z
 d
$

Você pode modificar o formato de saída para cada classe de linha.

Veja man diff ou info diff ou a documentação do GNU diffutils para mais informações.

    
por 14.10.2017 / 21:35