Combinando e colando para linha

7

Então eu tenho 2 arquivos de texto muito grandes, consistindo de linhas como:

Primeiro:

Robert:Dillain:Other:Other:Other
Julian:Brude:Other:Other:Other
Megan:Flikk:Other:Other:Other
Samantha:Minot:Other:Other:Other
Jesus:Kimmel:Other:Other:Other

Segundo:

Sb:Minot:amsen
Jbb:Kimmel:verlin
R:Dillain:bodent
Mb:Flikk:kentin
Jb:Brude:kemin

Gostaria de combinar os dois pela segunda coluna (Dillain, Brude, etc) e colá-los em linhas como esta:

OUTPUT:

Robert:Dillain:Other:Other:Other:R:Dillain:bodent
Jesus:Kimmel:Other:Other:Other:Jbb:Kimmel:verlin
Samantha:Minot:Other:Other:Other:Sb:Minot:amsen
etc...
etc...

Eu estava pensando em usar sed para isso, mas qualquer coisa baseada em Unix seria ótima. Eu não tive sorte tentando encontrar uma maneira de fazer isso sozinho.

    
por user104391 25.02.2015 / 02:38

4 respostas

8

Isso parece uma tarefa para join :

join -t":" -o "1.1,1.2,1.3,1.4,1.5,2.1,2.2,2.3" \
   -j 2 <(sort -k2,2 -t: test1) <(sort -k2,2 -t: test2)

Saída:

Julian:Brude:Other:Other:Other:Jb:Brude:kemin
Robert:Dillain:Other:Other:Other:R:Dillain:bodent
Megan:Flikk:Other:Other:Other:Mb:Flikk:kentin
Jesus:Kimmel:Other:Other:Other:Jbb:Kimmel:verlin
Samantha:Minot:Other:Other:Other:Sb:Minot:amsen

Divisão:

  • -t definiu o delimitador de campo para :
  • -o definir o formato de impressão
  • -j ingressar no número da coluna 2
  • <(sort -k2,2 -t: file) arquivo de pré-classificação por -k segunda coluna -t definir delimitador de campo para :
por 25.02.2015 / 03:39
5

Esta é uma tarefa simples para awk :

awk -F':' -vOFS=':' 'NR==FNR{a[$2]=$0;next}{print $0,a[$2]}' file2 file1

Primeiro, definimos : como separador de campos para entrada (com -F ) e saída (com OFS ), então se o primeiro arquivo for processado ( file2 ), atribuiremos linha inteira ao elemento de tabela indexado com segundo campo. Quando o próximo arquivo seguinte ( file1 ) é processado, imprimimos suas linhas adicionando a linha do arquivo anterior armazenado em a[$2] ).

    
por 25.02.2015 / 03:01
2

Com sed provavelmente você pode fazer:

sed 's|[^:]*:\([^:]*\).*|/^[^:]*::/s/$/:&/;t|' file2 | sed -f - file1

... o que envolveria um processo sed lendo o segundo arquivo e escrevendo um script sed para editar o primeiro em um segundo stdin sed . Tão perto quanto eu posso dizer que você não deve ter nenhum problema com a injeção direta do conteúdo textualmente em um regexp como esse. Se houver a possibilidade de metacaracteres na entrada, há muitas respostas neste site que discutem os meios de escapar delas. Se for necessário, no entanto, o seguinte seria suficiente:

sed 's|[]&\./*[]|\&|g;s|...' ... | sed -f - file1

Ainda assim, provavelmente, o epônimo join é a melhor solução - isso é apenas para demonstrar como fazer isso com sed porque você o mencionou.

De qualquer forma, o script que o segundo sed se aplica a file1 acaba parecido com (com uma linha semelhante à abaixo para cada linha no arquivo2) :

/^[^:]*:Dillain:/s/$/:R:Dillain:bodent/;t

... o que significa que se encontrar uma linha correspondente a Dillain para o segundo campo delimitado por dois pontos, então deve acrescentar a string : R: Dillain: bodent para a cauda. Como provavelmente não faz sentido continuar a tentar corresponder uma linha em file1 se uma linha de file2 já tiver sido anexada, o comando t est de finalização apenas removerá qualquer substituição bem-sucedida assim que estiver concluída. / p>     

por 25.02.2015 / 05:16
0

Através de python3

#!/usr/bin/python3
import csv
import sys
file1, file2 = sys.argv[1], sys.argv[2]
with open(file2) as second, open(file1) as first:
    second_list = second.readlines()
    first_list = first.readlines()
for line1 in first_list:
    for line2 in second_list:
        if line1.split(':')[1] == line2.split(':')[1]:
            print(line1.strip()+line2.strip())

Copie e cole o script acima em um arquivo chamado script.py . Em seguida, execute o script executando o comando abaixo no terminal.

python3 script.py file1 file2
    
por 25.02.2015 / 12:58

Tags