Search code examples
regexawksedterminalgnu

Inserting text with many newlines with gnu sed


I have a mainfile.txt that contains

 *
 * Some text
 *

Using the command

while read file; do gsed -i '1i'"$(cat mainfile.txt)" "$file";

I insert the text from mainfile.txt into the beginning of every file that matches some criteria. However, it seems like the different lines in mainfile.txt are causing trouble. The error says gsed: can't find label for jump to `o'. This error does not occur when mainfile.txt contains one line only. When trying to find a solution I only found out how to insert new lines in sed, which is not exactly what I am looking for.


Solution

  • i requires that each line to insert end in a backslash, except the last. If that's not the case for your file, it won't work.

    ed is a better choice for editing files than the non-standard sed -i, though if you're restricting yourself to GNU sed/gsed instead of whatever the OS-provided system sed is, that's less of an issue.

    With either command, the best solution to insert the contents of one file in another is to use the r command instead to read the contents of a file into the buffer after the addressed line (It acts more like a than i that way):

    printf "%s\n" "0r mainfile.txt" w | ed -s "$file"
    

    Unfortunately, sed doesn't take an address of 0 to mean "before the first line" like ed does so it's harder to use r here in it.


    Of course, just prepending one file to another can easily be done without either command:

    cat mainfile.txt "$file" > temp.txt && mv -f temp.txt "$file"
    

    or using sponge(1) from the moreutils package:

    cat mainfile.txt "$file" | sponge "$file"