AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / unix / Perguntas / 418429
Accepted
mindlessgreen
mindlessgreen
Asked: 2018-01-21 02:19:10 +0800 CST2018-01-21 02:19:10 +0800 CST 2018-01-21 02:19:10 +0800 CST

Encontre interseção de linhas em dois arquivos [duplicado]

  • 772
Esta pergunta já tem respostas aqui :
Gerar as linhas comuns (semelhanças) de dois arquivos de texto (o oposto de diff)? (5 respostas)
Linhas comuns entre dois arquivos [duplicado] (2 respostas)
Fechado há 4 anos .

Se eu tiver dois arquivos (com colunas únicas), um assim (arquivo1)

34
67
89
92
102
180
blue2
3454

E o segundo arquivo (arquivo2)

23
56
67
69
102
200

Como encontro elementos comuns nos dois arquivos (interseção)? A saída esperada neste exemplo é

67
102

Observe que o número de itens (linhas) em cada arquivo é diferente. Números e strings podem ser misturados. Eles podem não ser necessariamente classificados. Cada item aparece apenas uma vez.

ATUALIZAR:

Verificação de tempo com base em algumas das respostas abaixo.

# generate some data
>shuf -n2000000 -i1-2352452 > file1
>shuf -n2000000 -i1-2352452 > file2

#@ilkkachu
>time (join <(sort "file1") <(sort "file2") > out1)
real    0m15.391s
user    0m14.896s
sys     0m0.205s

>head out1
1
10
100
1000
1000001

#@Hauke
>time (grep -Fxf "file1" "file2" > out2)
real    0m7.652s
user    0m7.131s
sys     0m0.316s

>head out2
1047867
872652
1370463
189072
1807745

#@Roman
>time (comm -12 <(sort "file1") <(sort "file2") > out3)
real    0m13.533s
user    0m13.140s
sys     0m0.195s

>head out3
1
10
100
1000
1000001

#@ilkkachu
>time (awk 'NR==FNR { lines[$0]=1; next } $0 in lines' "file1" "file2" > out4)
real    0m4.587s
user    0m4.262s
sys     0m0.195s

>head out4
1047867
872652
1370463
189072
1807745

#@Cyrus   
>time (sort file1 file2 | uniq -d > out8)
real    0m16.106s
user    0m15.629s
sys     0m0.225s

>head out8
1
10
100
1000
1000001


#@Sundeep
>time (awk 'BEGIN{while( (getline k < "file1")>0 ){a[k]}} $0 in a' file2 > out5)
real    0m4.213s
user    0m3.936s
sys     0m0.179s

>head out5
1047867
872652
1370463
189072
1807745

#@Sundeep
>time (perl -ne 'BEGIN{ $h{$_}=1 while <STDIN> } print if $h{$_}' <file1 file2 > out6)
real    0m3.467s
user    0m3.180s
sys     0m0.175s

>head out6
1047867
872652
1370463
189072
1807745

A versão perl foi a mais rápida seguida pela awk. Todos os arquivos de saída tinham o mesmo número de linhas.

Para fins de comparação, classifiquei a saída numericamente para que seja idêntica.

#@ilkkachu
>time (join <(sort "file1") <(sort "file2") | sort -k1n > out1)
real    0m17.953s
user    0m5.306s
sys     0m0.138s

#@Hauke
>time (grep -Fxf "file1" "file2" | sort -k1n > out2)
real    0m12.477s
user    0m11.725s
sys     0m0.419s

#@Roman
>time (comm -12 <(sort "file1") <(sort "file2") | sort -k1n > out3)
real    0m16.273s
user    0m3.572s
sys     0m0.102s

#@ilkkachu
>time (awk 'NR==FNR { lines[$0]=1; next } $0 in lines' "file1" "file2" | sort -k1n > out4)
real    0m8.732s
user    0m8.320s
sys     0m0.261s

#@Cyrus   
>time (sort file1 file2 | uniq -d > out8)
real    0m19.382s
user    0m18.726s
sys     0m0.295s

#@Sundeep
>time (awk 'BEGIN{while( (getline k < "file1")>0 ){a[k]}} $0 in a' file2 | sort -k1n > out5)
real    0m8.758s
user    0m8.315s
sys     0m0.255s

#@Sundeep
>time (perl -ne 'BEGIN{ $h{$_}=1 while <STDIN> } print if $h{$_}' <file1 file2 | sort -k1n > out6)
real    0m7.732s
user    0m7.300s
sys     0m0.310s

>head out1
1
2
3
4
5

Todas as saídas agora são idênticas.

awk text-processing
  • 5 5 respostas
  • 31376 Views

5 respostas

  • Voted
  1. RomanPerekhrest
    2018-01-21T02:34:53+08:002018-01-21T02:34:53+08:00

    Simples comm+ sortsolução:

    comm -12 <(sort file1) <(sort file2)
    
    • -12- suprimir a coluna 1e 2(linhas exclusivas para FILE1e FILE2respectivamente), gerando apenas linhas comuns (que aparecem em ambos os arquivos)
    • 32
  2. Best Answer
    ilkkachu
    2018-01-21T02:30:33+08:002018-01-21T02:30:33+08:00

    Em awk, isso carrega o primeiro arquivo totalmente na memória:

    $ awk 'NR==FNR { lines[$0]=1; next } $0 in lines' file1 file2 
    67
    102
    

    Ou, se você quiser acompanhar quantas vezes uma determinada linha aparece:

    $ awk 'NR==FNR { lines[$0] += 1; next } lines[$0] {print; lines[$0] -= 1}' file1 file2
    

    joinpoderia fazer isso, embora exija que os arquivos de entrada sejam classificados, então você precisa fazer isso primeiro e, ao fazê-lo, perde a ordem original:

    $ join <(sort file1) <(sort file2)
    102
    67
    
    • 14
  3. Hauke Laging
    2018-01-21T02:28:59+08:002018-01-21T02:28:59+08:00

    estranho

    awk 'NR==FNR { p[NR]=$0; next; }
       { for(val in p) if($0==p[val]) { delete p[val]; print; } }' file1 file2
    

    Essa é a boa solução porque (para arquivos grandes) deve ser a mais rápida, pois omite a impressão da mesma entrada mais de uma vez e a verificação de uma entrada novamente após a correspondência.

    grep

    grep -Fxf file1 file2
    

    Isso geraria a mesma entrada várias vezes se ocorresse mais de uma vez em file2.

    ordenar

    Para se divertir (deve ser muito mais lento que grep):

    sort -u file1 >t1
    sort -u file2 >t2
    sort t1 t2 | uniq -d
    
    • 7
  4. Cyrus
    2018-01-21T03:18:30+08:002018-01-21T03:18:30+08:00

    Com GNU uniq:

    sort file1 file2 | uniq -d
    

    Resultado:

    102
    67
    
    • 3
  5. Sundeep
    2018-01-21T05:10:44+08:002018-01-21T05:10:44+08:00

    versão ligeiramente diferente e versão awkequivalenteperl

    tempo relatado para três execuções consecutivas

    $ # just realized shuf -n2000000 -i1-2352452 can be used too ;)
    $ shuf -i1-2352452 | head -n2000000 > f1
    $ shuf -i1-2352452 | head -n2000000 > f2
    
    $ time awk 'NR==FNR{a[$1]; next} $0 in a' f1 f2 > t1
    real    0m3.322s
    real    0m3.094s
    real    0m3.029s
    
    $ time awk 'BEGIN{while( (getline k < "f1")>0 ){a[k]}} $0 in a' f2 > t2
    real    0m2.731s
    real    0m2.777s
    real    0m2.801s
    
    $ time perl -ne 'BEGIN{ $h{$_}=1 while <STDIN> } print if $h{$_}' <f1 f2 > t3
    real    0m2.643s
    real    0m2.690s
    real    0m2.630s
    
    $ diff -s t1 t2
    Files t1 and t2 are identical
    $ diff -s t1 t3
    Files t1 and t3 are identical
    
    $ du -h f1 f2 t1
    15M f1
    15M f2
    13M t1
    
    • 3

relate perguntas

  • Reorganize as letras e compare duas palavras

  • Subtraindo a mesma coluna entre duas linhas no awk

  • Embaralhamento de arquivo de várias linhas

  • como posso alterar o caso do caractere (de baixo para cima e vice-versa)? ao mesmo tempo [duplicado]

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    Como exportar uma chave privada GPG e uma chave pública para um arquivo

    • 4 respostas
  • Marko Smith

    ssh Não é possível negociar: "nenhuma cifra correspondente encontrada", está rejeitando o cbc

    • 4 respostas
  • Marko Smith

    Como podemos executar um comando armazenado em uma variável?

    • 5 respostas
  • Marko Smith

    Como configurar o systemd-resolved e o systemd-networkd para usar o servidor DNS local para resolver domínios locais e o servidor DNS remoto para domínios remotos?

    • 3 respostas
  • Marko Smith

    Como descarregar o módulo do kernel 'nvidia-drm'?

    • 13 respostas
  • Marko Smith

    apt-get update error no Kali Linux após a atualização do dist [duplicado]

    • 2 respostas
  • Marko Smith

    Como ver as últimas linhas x do log de serviço systemctl

    • 5 respostas
  • Marko Smith

    Nano - pule para o final do arquivo

    • 8 respostas
  • Marko Smith

    erro grub: você precisa carregar o kernel primeiro

    • 4 respostas
  • Marko Smith

    Como baixar o pacote não instalá-lo com o comando apt-get?

    • 7 respostas
  • Martin Hope
    rocky Como exportar uma chave privada GPG e uma chave pública para um arquivo 2018-11-16 05:36:15 +0800 CST
  • Martin Hope
    Wong Jia Hau ssh-add retorna com: "Erro ao conectar ao agente: nenhum arquivo ou diretório" 2018-08-24 23:28:13 +0800 CST
  • Martin Hope
    Evan Carroll status systemctl mostra: "Estado: degradado" 2018-06-03 18:48:17 +0800 CST
  • Martin Hope
    Tim Como podemos executar um comando armazenado em uma variável? 2018-05-21 04:46:29 +0800 CST
  • Martin Hope
    Ankur S Por que /dev/null é um arquivo? Por que sua função não é implementada como um programa simples? 2018-04-17 07:28:04 +0800 CST
  • Martin Hope
    user3191334 Como ver as últimas linhas x do log de serviço systemctl 2018-02-07 00:14:16 +0800 CST
  • Martin Hope
    Marko Pacak Nano - pule para o final do arquivo 2018-02-01 01:53:03 +0800 CST
  • Martin Hope
    Kidburla Por que verdadeiro e falso são tão grandes? 2018-01-26 12:14:47 +0800 CST
  • Martin Hope
    Christos Baziotis Substitua a string em um arquivo de texto enorme (70 GB), uma linha 2017-12-30 06:58:33 +0800 CST
  • Martin Hope
    Bagas Sanjaya Por que o Linux usa LF como caractere de nova linha? 2017-12-20 05:48:21 +0800 CST

Hot tag

linux bash debian shell-script text-processing ubuntu centos shell awk ssh

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve