Skip to content Skip to sidebar Skip to footer

Create String With Backslashes For Use By Sed

I'm creating a command string in python that needs to be executed on a host using pexpect. The sed command that I wish to run on the host is as below: sed -i 's/\(panic=30\)/\1 my_

Solution 1:

This confused me on first read of your question, but take a look at the string literals page

As you probably know, python uses the backslash character \ as an escape character. So to include a new line in a string literal, we type

s = 'hello\nworld'

If we want an actual backslash, we use a double backslash

s = '\\'

If the character following the backslash doesn't match an escape sequence, the backslash is kept as is

s = '\ ' # space doesn't match any escape sequence, so you get to keep the backslash

This is what happens with your \( - you end up with <backslash><open parnes>

However \1 does match an escape sequence - it's the literal for an octal representation of a character. So instead of <backslash>1, you got <0x01>.

When you use p cmd in pdb, it's printing the repr of the string, which happens to use backslash escaping for non-printable characters. This is different to using print cmd in the python shell.

python shell:
>>> print '\\'
\

pdb:
(Pdb) p '\\'
'\\'

Pdb is showing you that you have a single backslash. Similar to

>>> print repr('\\')
'\\'

So when you said

(Pdb) p cmd
"sed -i 's/\\(panic=30\\)/\\1 ignorefs/g' /boot/bootrc"

All of the double backslash pairs there are single backslash characters. The difference with your working example in the comments is that you have literal backslashes in front of your open/close parens.

Finally, if you don't want to worry about backslash escaping, you can use raw strings

>>> s = r"sed -i 's/\(panic=30\)/\1 my_cool_option/g' /boot/bootrc"
>>> print s
sed -i 's/\(panic=30\)/\1 my_cool_option/g' /boot/bootrc
>>> print repr(s)
"sed -i 's/\\(panic=30\\)/\\1 my_cool_option/g' /boot/bootrc"

Solution 2:

I see that your question has been answered, but for future reference, if you have a string with backslashes and you want to be sure that it contains what you think it should, you can scan through it char by char and print it, eg

#! /usr/bin/env python

mystring = "this\nis\t a \complicated\\string"
print repr(mystring), len(mystring)
for i,v in enumerate(mystring):
    print "%2d: %-4r %02x" % (i, v, ord(v))

output

'this\nis\t a \\complicated\\string' 30
 0: 't'  74
 1: 'h'  68
 2: 'i'  69
 3: 's'  73
 4: '\n' 0a
 5: 'i'  69
 6: 's'  73
 7: '\t' 09
 8: ' '  20
 9: 'a'  61
10: ' '  20
11: '\\' 5c
12: 'c'  63
13: 'o'  6f
14: 'm'  6d
15: 'p'  70
16: 'l'  6c
17: 'i'  69
18: 'c'  63
19: 'a'  61
20: 't'  74
21: 'e'  65
22: 'd'  64
23: '\\' 5c
24: 's'  73
25: 't'  74
26: 'r'  72
27: 'i'  69
28: 'n'  6e
29: 'g'  67

Post a Comment for "Create String With Backslashes For Use By Sed"