Saturday, November 13, 2021

[SOLVED] Replace file line with multi-line, special char string

Issue

I'm trying to automate generating a README.md.

The idea is:

  1. Generate markdown table string like...

    table="| Image | Name | Description | Notes |\n"
    table+="| --- | --- | --- | --- |\n"
    table+="| $img1 | $name1 | $desc1 | $notes1 |\n"
    table+="| $img2 | $name2 | $desc2 | $notes2 |\n"
    ...
    

    *simplified

    *contains special characters like e.g. |-()[]/<>

  2. Replace <!-- insert-table-here --> in a readme_template.md file with the full table

    ## Header
    
    <!-- insert-table-here -->
    
    <sub>More info...</sub>
    
  3. Save new file as README.md

I can't get step 2 working.

How do you replace a line in a file with a multi-line, special char ridden string?

Every sed, awk, perl, or even head/tail command I try seems to not work. Are heredocs the better approach?

I have found some hack solutions for specific cases with specific chars but I want to identify a more robust method.

EDIT: Thanks to @potong, this is what ended up working for me.

echo -e ${table} | sed -e '/<!-- insert-table-here -->/{r /dev/stdin' -e 'd}' readme_template.md > README.md

EDIT 2: After spending some more time on this, I found a nice multi-match option through awk

awk \
  -v t1="$(generate_table1)" \
  -v t2="$(generate_table2)" \
  '{
    gsub(/<!-- insert-table-1 -->/,t1)
    gsub(/<!-- insert-table-2 -->/,t2)
  }1' \
  readme_template.md > README.md

Solution

This might work for you (GNU sed and bash):

cat <<\! | sed -e '/<!-- insert-table-here -->/{r /dev/stdin' -e 'd}' file
Here is a heredoc
with special symbols
{}-()[]/<>
!

The heredoc is piped through to the sed command using /dev/stdin as a file for the r command, then the original line is deleted using the d command.

N.B. The use of the -e command line option to split the two parts of the sed script (oneliner). This is necessary because the r command needs to be terminated by a newline and the -e option provides this functionality.



Answered By - potong