awkで2つのファイルのデータをマージする方法

awkで2つのファイルのデータをマージする方法

2つのファイルがありますA.txtB.txt

A.txt(9 月 = \t):

Well    Sample Name Target Name Task    Reporter
A1  B1000-1 MS2 UNKNOWN JUN 
A1  B1000-1 Ngene   UNKNOWN VIC 
A1  B1000-1 ORF1ab  UNKNOWN FAM 
A1  B1000-1 Sgene   UNKNOWN ABY 
A2  B500-3  MS2     UNKNOWN JUN 
A2  B500-3  Ngene   UNKNOWN VIC 
A2  B500-3  ORF1ab  UNKNOWN FAM

とB.txt(9月=;)

kit;;;;;;;
Software Version = cti;;;;;;;
Date And Time of Export = 06/02/20  14:14:11;;;;;;;
Experiment Name = taq;;;;;;;
Instrument Software Version = ;;;;;;;
Instrument Type = sds7500fast;;;;;;;
Instrument Serial Number = ;;;;;;;
Run Start Date = Tue Jun 02 12:00:40 CEST 2020;;;;;;;
Run End Date = Tue Jun 02 13:14:42 CEST 2020;;;;;;;
Run Operator = FE;;;;;;;
Batch Status = VALID;;;;;;;
;;;;;;;
Date And Time of Export;Batch ID;Sample Name;Well;Sample Type;Status;Interpretive;Action*;Cт
06/02/2020 14:14;020620 TAQPATH BIS;B50-1-KF;H2;Patient;VALID;SARS-CoV-2 Not Detected;REPORT;29.2525;Undetermined;16.0231;33.9412

出力ファイルからこれを取得したいですC.txt

kit;;;;;;;
Software Version = cti;;;;;;;
Date And Time of Export = 06/02/20  14:14:11;;;;;;;
Experiment Name = taq;;;;;;;
Instrument Software Version = ;;;;;;;
Instrument Type = sds7500fast;;;;;;;
Instrument Serial Number = ;;;;;;;
Run Start Date = Tue Jun 02 12:00:40 CEST 2020;;;;;;;
Run End Date = Tue Jun 02 13:14:42 CEST 2020;;;;;;;
Run Operator = FE;;;;;;;
Batch Status = VALID;;;;;;;
;;;;;;;
Date And Time of Export;Batch ID;Sample Name;Well;Sample Type;Status;Interpretive;Action*;MS2;Ngene;ORF1ab;Sgene
06/02/2020 14:14;020620 TAQPATH BIS;B50-1-KF;H2;Patient;VALID;SARS-CoV-2 Not Detected;REPORT;29.2525;Undetermined;16.0231;33.9412

A1A.txtしたがって、inで始まる行をフィルタリングし、その行の3番目のフィールドを13行目の9番目のフィールドにコピーしたいと思いますB.txt

別のFNR==NRでいくつかのテストを行いましたが、決定的な結果はありませんでした。

ありがとう

ベストアンサー1

1つの方法は次のとおりです。

$ awk -F'[;\t]' '{if(NR==FNR){if($1=="A1"){s==""?s=$3:s=s";"$3;}}else{if(FNR==13){$9=s;}OFS=";";print}}' A.txt B.txt 
kit;;;;;;;
Software Version = cti;;;;;;;
Date And Time of Export = 06/02/20  14:14:11;;;;;;;
Experiment Name = taq;;;;;;;
Instrument Software Version = ;;;;;;;
Instrument Type = sds7500fast;;;;;;;
Instrument Serial Number = ;;;;;;;
Run Start Date = Tue Jun 02 12:00:40 CEST 2020;;;;;;;
Run End Date = Tue Jun 02 13:14:42 CEST 2020;;;;;;;
Run Operator = FE;;;;;;;
Batch Status = VALID;;;;;;;
;;;;;;;
Date And Time of Export;Batch ID;Sample Name;Well;Sample Type;Status;Interpretive;Action*;MS2;Ngene;ORF1ab;Sgene
06/02/2020 14:14;020620 TAQPATH BIS;B50-1-KF;H2;Patient;VALID;SARS-CoV-2 Not Detected;REPORT;29.2525;Undetermine

または読みやすくなります。

awk -F'[;\t]' '{
     if(NR==FNR){
        if($1=="A1"){
           if(s==""){ s=$3 }
           else{ s=s";"$3 }
         }
     else{
        if(FNR==13){ $9=s; } 
          OFS=";"; 
          print
        }
     }' A.txt B.txt > C.txt

説明する:

  • -F'[;\t]':両方のファイルが正しく読み取れるように、;フィールド区切り文字をorに設定します。\t気づくこれはno ;infileAとno \tinを仮定します。fileB
  • if(NR==FNR){:最初のファイルを読み取る場合。
  • if($1=="A1"){:最初のフィールドがA1
  • s==""?s=$3:s=s";"$3;:変数sが空の場合は値に設定します$3。空でない場合は、aを追加してからを;追加します$3。これにより、挿入する文字列が作成されますB.txt
  • else { :2番目のファイルを読む場合(完了しましたif(NR==FNR))。
  • if(FNR==13){ $9=s; }:現在のファイルの13行目の場合は、9番目のフィールドを値に設定しますs
  • OFS=";"; print:2番目のファイルのすべての行を印刷したいが、;正しく印刷するにはフィールド区切り文字を出力する必要があります。

おすすめ記事