1つのファイルのパターンに一致する行を取得し、同じパターンに一致する2番目のファイルに入れます。

1つのファイルのパターンに一致する行を取得し、同じパターンに一致する2番目のファイルに入れます。

それぞれ「b」文字で始まる行を含む2つのファイルがあり、最初のファイルに表示される順序で行をマージしたいとします。

最初のファイル(1.txt)

b 12 32
b 23 43
b 23 63

2番目のファイル(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

2番目のファイルでは、「b」文字で始まる行には情報が含まれなくなりますが、最初のファイルでは私の行が「b」で始まり、その後に整数値が続くことがわかります。

今必要なのは、最初のファイルから整数を取得し、最初のファイルに表示されるように「b」行の2番目のファイルに入れることです。したがって、2番目のファイルは次のように表示する必要があります。

マージファイル(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  

参加するこのコマンドは私が望むことをすることができるようですが、先行する "b"文字と一致する行でのみ機能するように指示する方法を見つけることができません。また、ファイル1を繰り返して「^ b」パターンに一致する行番号を取得し、それを使用して「^ b」パターンに一致するファイル2の行を置き換えることも検討しましたが、再び動作する解決策が見つかりませんでした。 。私のタスクを実行するための短いbashスクリプトを知っている人はいますか?

答え1

GNU sedの使用:

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

2.txtファイルを「位置」で編集するには、sedオプションを追加してください-i

答え2

そしてawk

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

まず、 file1 の内容で配列を埋めa、 file2 が処理されると文字 "b" だけを含む行の代わりに配列が印刷されます。

答え3

Perlを使うと簡単になるかもしれませんが、まだPerlを学んだことはありません。

awkこれにはいくつかのトリックを使用できます。

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

これにより、最初のファイルのすべての行が名前付き配列に保存され、lineその行が2番目のファイルの一致する行に配置されます/^b/

答え4

Pythonがここで役に立つかもしれません。

    #!/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()

関連情報