1 min read

How to preserve backslashes when using sed command

How to preserve backslashes when using sed command

Today I faced an interesting task. I wanted to generate a bunch of yaml files with different names to test some payloads. Each time I generated a yaml file, I needed to uploaded the file to the system manually, check the result and then move to the next generated file.

So this is the yaml template:

metadata:
  name: replaceme
...omitted...

And the file with payloads, say:

\x3C
\u003c
...omitted...

The first thought is to use sed to replace the replaceme string with the payload. So potential script would look like so:

for line in $(cat payloads.txt); do
  echo "> "$line
  sed "s/replaceme/$line/" yaml_template.yaml > final_yaml.yaml
  read -p "Press any key to continue..."
done

The problem with the script is that sed considers backslashes (\) as an escape symbol, so the resulting yaml for the first payload will look like

metadata:
  name: x3c
...omitted...

Solution

What would be the solution in this case? We can use the printf command to workaround this situation:

for line in $(cat payloads.txt); do
  echo "> "$line
  sed "s/replaceme/$(printf %q "$line")/" yaml_template.yaml > final_yaml.yaml
  read -p "Press any key to continue..."
done

which will produce the correct yaml:

metadata:
  name: \x3c
...omitted...