Linux Sed Command - Using Variable with Backslash

How to pass a variable containing slashes to sed

Use an alternate regex delimiter as sed allows you to use any delimiter (including control characters):

sed "s~$var~replace~g" $file

As mentioned above we can use control character as delimiter as well like:

sed "s^[$var^[replace^[g" file

Where ^[ is typed by pressing Ctrl-V-3 together.

Or else in bash shell you can use this sed with \03 as delimiter:

d=$'\03'
sed "s${d}$var${d}replace$d" file

Linux sed command - using variable with backslash

Try this:

cd /tmp
mkdir -p 1234567
echo Hello World >1234567/myfile.txt
echo '1234567#Hello World#Hello I\u0027m Scott' >text.txt

Well, then:

IFS=\# read -r FOLDERID oldstring newstring <text.txt 
sed "s/${oldstring}/${newstring//\\/\\\\}/g" -i $FOLDERID/myfile.txt
cat 1234567/myfile.txt
Hello I\u0027m Scott

Variable contains backslash not working in sed bash

You can freely change your delimiter of sed's regular expression by preceding it with a backslash, e.g. \!. Following command should work:

sed -n '\!'"$LAST"'!,\!'"$NOW"'!p' /var/log/apache2/domlogs/access.log

If ! is expected to show up in your date time format, you can use your judgment to choose another one.

You should read some good sed tutorial before working with sed, e.g.: http://www.grymoire.com/Unix/sed.html


I think you originally want to implement a range search in sed while you might miss the syntax of that. I fixed it above and it's tested.

Replace one backslash with two backslashes using sed

You need to escape the backslashes, so \ becomes \\:

sed 's,\\,\\\\,g'

or the slightly more hard to read for people with eyesight like my own:

sed 's/\\/\\\\/g'

How can I insert a variable containing a backslash in sed?

If it's only backslash that is "eaten" by sed and escaping just that is enough, then try:

echo "a" | sed "s|a|${tmp//\\/\\\\}|g"

Confusing enough for you? \\ represents a single \ since it needs to be escaped in the shell too.
The inital // is similar to the g modifier in s/foo/bar/g, if you only want the first occurring pattern to be replaced, skip it.

The docs about ${parameter/pattern/string} is available here: http://www.gnu.org/s/bash/manual/bash.html#Shell-Parameter-Expansion

Edit: Depending on what you want to do, you might be better of not using sed for this actually.

$ tmp="UY\U[_"
$ in="a"
$ echo ${in//a/$tmp}
UY\U[_

How to insert strings containing slashes with sed?

The easiest way would be to use a different delimiter in your search/replace lines, e.g.:

s:?page=one&:pageone:g

You can use any character as a delimiter that's not part of either string. Or, you could escape it with a backslash:

s/\//foo/

Which would replace / with foo. You'd want to use the escaped backslash in cases where you don't know what characters might occur in the replacement strings (if they are shell variables, for example).

Escape twice special characters using sed

One backslash is used to change an argument to text or vice versa.

echo 'Uploaded registry/version1.3.1' | sed 's/\//\\\\\//g'
Uploaded registry\\/version1.3.1

In this case you need \\ for one backslash and \/for a slash.

Escape backslash character in sed

Assuming your path variable was assigned properly (without spaces in the assignment: path='first\usr'), fixing step by step for an input file test.txt with one example path:

$ cat test.txt
D:\usr
  1. Your original command

    $ sed 's!\\usr!${path}/g;' test.txt
    sed: -e expression #1, char 18: unterminated `s' command

    doesn't do much, as you've mixed ! and / as the delimiter.

  2. Fixing delimiters:

    $ sed 's!\\usr!${path}!g;' test.txt
    D:${path}

    Now no interpolation happens at all because of the single quotes. I suspect these are just copy-paste mistakes, as you obviously got some output.

  3. Double quotes:

    $ sed "s!\\usr!${path}!g" test.txt
    bash: !\\usr!${path}!g: event not found

    Now this clashes with history expansion. We could escape the !, or use a different delimiter.

  4. / as delimiter:

    $ sed "s/\\usr/${path}/g" test.txt
    D:\firstSr

    Now we're where the question actually started. ${path} expands to first\usr, but \u has a special meaning in GNU sed in the replacement string: it uppercases the following character, hence the S.

    Even without the special meaning, \u would most likely just expand to u and the backslash would be gone.

  5. Escaping the backslash:

    $ path='first\\usr'
    $ sed "s/\\usr/${path}/g" test.txt
    D:\first\usr

    This works.

Escape backslash with sed command when the next character is t

sed $'/^##INFO=<ID=/{ s//'\t%INFO' /; s/,.*//; p; }''

1.)The dollar sign in front doesn't seem to have a point

sed '/^##INFO=<ID=/{ s//'\t%INFO' /; s/,.*//; p; }''

2.)You cant just nest single quotes. I dont know how this "works" I wouldnt expect it to.

sed '/^##INFO=<ID=/{ s//\t%INFO /; s/,.*//; p; }'

3.) This replaces the string with a tab then a %INFO. Then prints it. escape it once.

sed '/^##INFO=<ID=/{ s//\\t%INFO /; s/,.*//; p; }'

4.) This replaces the stinge with a \t%INFO then prints it, resulting in tab %INFO. Escape it again.

sed '/^##INFO=<ID=/{ s//\\\\t%INFO /; s/,.*//; p; }'

5.)This should work.

But there is an easier answer using a capture group. It looks like you are looking for this?

bcftools view -h /data/ExAC.r1.sites.vep.vcf \
| grep "^##INFO=<ID=" \
| sed -E 's/^##INFO=<ID=([^,]*),.*/\\t%INFO \1/'

To get all on on line:

bcftools view -h /data/ExAC.r1.sites.vep.vcf \
| grep "^##INFO=<ID=" \
| sed -E 's/^##INFO=<ID=([^,]*),.*/\\t%INFO \1/' \
| awk '{printf "%s ", $0}'


Related Topics



Leave a reply



Submit