1

I recently asked a similar question How To Insert File Contents After Line Match While Escaping Backslash only to realize I need to do the opposite.

Using the code from that question, I have tried:

sed '/<\\tag>/i file2' file1

2nd attempt:

awk '/<\\tag>/{print;system("cat File2.txt");before} 1' File1.txt

However, I'm unable to get it to insert one line before the match.

Example:

File1.txt

Hello <[World!]> 1
Hello <[World!]> 2

File2.txt:

<thanks>
<tag>
<example>
<new>
<\new>
<\example>
<\tag>
<\thanks>

Desired output:

<thanks>
<tag>
<example>
<new>
<\new>
<\example>
Hello <[World!]> 1
Hello <[World!]> 2
<\tag>
<\thanks>

If you could please help me insert the file contents after a line match while escaping a backslash, I would really appreciate it.

DomainsFeatured
  • 1,426
  • 1
  • 21
  • 39
  • It's possible in `sed`, but it's ugly and doesn't work if the match is on the last line. `sed '/<\\tag>/{r file1.txt; h; d; }; H; s/.*//; x; s/^\n//' file2.txt` – Kevin Oct 12 '17 at 22:36
  • Hey Kevin, thanks for trying. I got this `sed: -e expression #1, char 0: unmatched `{'` when checking – DomainsFeatured Oct 12 '17 at 22:38

2 Answers2

2
$ awk 'FNR==NR{n=n $0 ORS; next} /<\\tag>/{$0=n $0} 1' file1 file2
<thanks>
<tag>
<example>
<new>
<\new>
<\example>
Hello <[World!]> 1
Hello <[World!]> 2
<\tag>
<\thanks>
Ed Morton
  • 188,023
  • 17
  • 78
  • 185
1

In your awk solution you need to do following changes :
1. Interchange the file names as you've to work upon File2.txt and print the File1.txt contents where the match is found.
2. Remove the print; in awk as you don't want to print the <\tag> twice in your output.
3. There is no keyword before in awk. Remove it please.

awk '/<\\tag>/{system("cat File1.txt");} 1' File2.txt

Other possible solution is :

$ awk 'FNR==NR{f1[++i]=$0; l=i; next} /<\\tag>/{ for(i=1; i<=l; i++) print f1[i]}1' File1.txt File2.txt
<thanks>
<tag>
<example>
<new>
<\new>
<\example>
Hello <[World!]> 1
Hello <[World!]> 2
<\tag>
<\thanks>

FNR==NR{f1[$0]=$0; next} Stores the content of File1.txt in array f1
/<\\tag>/{ for(i in f1) print f1[i]} : While iterating over File2.txt if the match is found then print the array contents.

Rahul Verma
  • 2,946
  • 14
  • 27
  • The first one gives me an error. The second one works but the lines are out of order. Don't drive yourself crazy. I'm going to work around around it. You already helped me a lot today. – DomainsFeatured Oct 12 '17 at 22:20
  • @DomainsFeatured: What error are you getting in first case ? – Rahul Verma Oct 12 '17 at 22:24
  • `file1.txt: line 1: [World!]: No such file or directory` and `file1.txt: line 2: [World!]: No such file or directory` – DomainsFeatured Oct 12 '17 at 22:26
  • 1
    @DomainsFeatured: I've done changes for 2nd solution which will maintain the order. Let me see why first one is not working for you. – Rahul Verma Oct 12 '17 at 22:31
  • 1
    @EdMorton Ah, sorry. I will wait longer in the future. Missed a good opportunity to work with you again :-) – DomainsFeatured Oct 12 '17 at 22:40
  • @EdMorton: Any idea why the first one which was similar to what suggested by OP itself wasn't working at his end. It was wokring fine my side. – Rahul Verma Oct 13 '17 at 05:21
  • 1
    My best guess is that the OP didn't execute the same command you posted but instead had some other command being called by system() because the command you posted cannot produce those error messages AFAIK. – Ed Morton Oct 13 '17 at 13:50