1

I have two files, A.txt and B.txt:

A.txt (sep = \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

and B.txt (sep = ;)

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

And I want to get this in the output file, 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

So I want to screen the lines that begin with A1 in A.txt and copy the 3rd fields of these lines as 9th field of line 13 of B.txt.

I've done some test with different FNR==NR but I have no conclusive result..

Thanks

1 Answer 1

0

Here's one way:

$ 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

Or, a little easier to read:

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

Explanation:

  • -F'[;\t]': this sets the field separator to either ; or \t so we can read both files correctly. Note that this assumes there are no ; in fileA and no \t in fileB.
  • if(NR==FNR){: if we are reading the first file.
  • if($1=="A1"){: if the first field is A1.
  • s==""?s=$3:s=s";"$3;: if the variable s is empty, set it to the value of $3. If it isn't empty, add a ; and then $3. This builds up the string we will want to insert into B.txt.
  • else { : if we are reading the second file (this completes the if(NR==FNR)).
  • if(FNR==13){ $9=s; }: if this is the 13th line of the current file, set the 9th field to the value of s.
  • OFS=";"; print: we want to print all lines from the second file, but we need the output field separator to be ; so they're printed correctly.
3
  • Thanks for the answer and the full explanation of the command, it's very helpful !
    – nstatam
    Jun 11, 2020 at 10:39
  • {if (NR==FNR) { a } else { b }} is usually written NR==FNR{ a; next } { b }. It'll behave the same either way of course, just cuts down on the indenting and means you can do more in the condition section of the script when processing the 2nd file so you can write cond { act } instead of { if ( cond ) { act } }.
    – Ed Morton
    Jun 11, 2020 at 19:56
  • 1
    @EdMorton Thanks, I'm quite familiar with both idioms and use both in my answers as my mood or circumstance dictates.
    – terdon
    Jun 11, 2020 at 20:01

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.