Obtenha linhas que correspondam a um padrão em um arquivo e coloque-as em um segundo arquivo que corresponda ao mesmo padrão

4

Digamos que eu tenha 2 arquivos contendo linhas que começam com um caractere 'b' e quero apenas mesclar essas linhas na mesma ordem em que aparecem no primeiro arquivo.

Primeiro arquivo (1.txt)

b 12 32
b 23 43
b 23 63

Segundo arquivo (2.txt)

a 1322
c 233
g 23324
s 24352

b
h vd2 3f4g

a 2t42
c 34536
g h3443e
s 24h455

b
h 3434gggdfbv4

a 423gwg
c f24bv
g 34g 45h
s 4zth5

b
h 3456zh543

Você pode ver que no segundo arquivo as linhas que começam com um caractere 'b' não contêm mais nenhuma informação, enquanto no primeiro arquivo eu tenho linhas que começam apenas com um 'b' seguido por alguns valores inteiros. / p>

O que eu preciso agora é algo que obtenha os inteiros do primeiro arquivo e os coloque nas linhas 'b' do segundo arquivo da mesma maneira que aparece no primeiro arquivo. Então, o segundo arquivo deve ser assim:

arquivo mesclado (3.txt)

a 1322  
c 233  
g 23324  
s 24352  

b 12 32  
h vd2 3f4g  

a 2t42  
c 34536  
g h3443e  
s 24h455  

b 23 43  
h 3434gggdfbv4  

a 423gwg  
c f24bv  
g 34g 45h  
s 4zth5  

b 23 63  
h 3456zh543  
O comando

join parece ser capaz de fazer o que eu quero, mas não consigo encontrar uma maneira de dizer que ele só funcione em linhas que combinem com o caractere 'b' inicial. Também pensei em um loop percorrendo o arquivo 1 para obter os números de linha correspondentes ao padrão '^ b' e usá-los para substituir as linhas correspondentes ao padrão '^ b' no arquivo 2, mas novamente não consigo encontrar uma solução de trabalho. Alguém tem uma idéia para realizar minha tarefa com um one-liner ou um script curto?

    
por tobi 03.01.2016 / 20:13

4 respostas

5

Com o GNU sed:

sed -e '/^b/{R 1.txt' -e 'd}' 2.txt

se você quiser editar o arquivo 2.txt "no lugar", adicione a opção sed do -i .

    
por 03.01.2016 / 20:55
4

com awk :

awk 'NR==FNR{a[++i]=$0;next}$0=="b"{$0=a[++j]}1' file1 file2

Primeiro, preenchemos a matriz a com o conteúdo do arquivo1 e quando o arquivo2 está sendo processado, a matriz é impressa no lugar das linhas que contêm apenas a letra "b".

    
por 03.01.2016 / 20:58
2

Provavelmente seria mais fácil em Perl, mas ainda não aprendi Perl.

Você pode fazer isso em awk com um truque:

awk 'NR == FNR { line[NR] = $0; next } /^b/ { $0 = line[++whichline] } 1' 1.txt 2.txt > 3.txt

Isso armazena todas as linhas do primeiro arquivo na matriz chamada line e, em seguida, coloca essas linhas no segundo arquivo nas linhas correspondentes a /^b/ .

    
por 03.01.2016 / 20:58
2

O Python pode ajudar aqui:

    #!/bin/env python
    fileA=open('filea','r')
    fileB=open('fileb','r')
    resultFile = open('resultfile','w')
    linesA=fileA.readlines()
    i=0
    for line in fileB:
      if line.lstrip().startswith('b'):
        resultFile.write(linesA[i].rstrip())
        i=i+1
      else:
        resultFile.write(line)
   fileA.close()
   fileB.close()
   resultFile.close()
    
por 03.01.2016 / 21:10