Replicating certain lines in a textfile

I am very new to to shell scripting and facing a problem that I can't seem to solve. I want to write a bash script that edits file1.txt and saves it as file2.txt.
This is what the files should look like:
file1:

textline1
textline2
startCopy
copyThis
endCopy
textline3
textline4

file2:

textline1
textline2
startCopy
copyThis
endCopy
startCopy
copyThis
endCopy
startCopy
copyThis
endCopy
textline3
textline4

This is just a short example, there are way more lines. What I want to do is replicate certain lines (and I know what the startline and endline looks like) very often.
I think (unfortunaely I can't test it anymore before tomorrow)

 awk '/^startCopy/,/^endCopy/ {print}' file1.txt >>file2.txt 

will copy the three lines to a new file file2.txt.
But how can I keep the content of file1.txt and print the three lines to the right position?

Try

awk '/^startCopy/,/^endCopy/ {X=X $0 "\n"; if (/^endCopy/) for (i=1; i<=REPEAT; i++) printf X; next} 1' REPEAT=3 file
textline1
textline2
startCopy
copyThis
endCopy
startCopy
copyThis
endCopy
startCopy
copyThis
endCopy
textline3
textline4
1 Like

Thank you very much! It works fine, but I still have trouble to find out what every part of the code does. What does

X=X $0 "\n";

for example do? I understand that $0 means the whole line and \n is newline, but what about the X=X in this context?
Is there a way to have the for-loop outside of the awk-command? That would be useful, because later I will need several for-loops around it. I tried things like

REPEAT=3
for((i=1; i<=REPEAT; i++))
do
  awk '/^startCopy/, /^endCopy/ {X=X $0 "\n"; if(/^endCopy/)  printf X; next}1  ' file1.txt >> file2.txt
done

But that gives me the whole file three times insted of just a part of it.

X=X $0 "\n"; is a concatenation of X plus $0 plus \n, then assigned to X.

That external for loop will of course print the entire file REPEAT times. If your entire problem were known, it possibly might be solvable entirely in awk .

Thank you! I wanted to keep it simple an face the problem step by step, but that might be confusing, too. So here is the whole problem:
file1.txt is a template that looks like this:

textline1
textline2
startCopy
copyThisMMDD
endCopy
textline3
textline4

where MM stands for month (0..12) and DD for day (I managed to check with if-constructions how many days one month has. I want to copy and paste the three lines for every month and day, so that I get:

textline1
textline2
startCopy
copyThis0101
endCopy
startCopy
copyThis0102
endCopy
....
startCopy
copyThis1230
endCopy
startCopy
copyThis1231
endCopy
textline3
textline4

I would do that with two for loops, maybe I will need more in the future for years.
So my initial problem is to copy and paste the three lines. I think I be able to substitute the template MMDD with sed.

Would this help:

awk     '
BEGIN           {split ("31 28 31 30 31 30 31 31 30 31 30 31", MTH)}
$0 ~ START      {TGT = NR + 1; next} 
NR==TGT         {COP = $0; next}

$0 ~ FIN        {for (i=1; i<=12; i++)
                        for (j=1; j<=MTH; j++)
                                {TMP = COP
                                 M=sprintf ("%02d", i)
                                 D=sprintf ("%02d", j)
                                 sub (/MM/, M, TMP)
                                 sub (/DD/, D, TMP)
                                 printf "%s\n%s\n%s\n", START, TMP, FIN
                                }
                 next
                }
1
'  START="startCopy" FIN="endCopy" file
textline1
textline2
startCopy
copyThis0101
endCopy
.
.
.
startCopy
copyThis1231
endCopy
textline3
textline4
1 Like

Thank you so much! I finally managed to understand every part of your code and could even adapt it as my input has slightly changed to just one line that needs to be copied :cool:
This helped me a lot :slight_smile: