简体   繁体   中英

Sed escaping from inside Ruby

I have a Ruby script that calls 'sed' as so:

    command = "sed -i \"s*#{find_what]}*#{replace_with}*\" #{file} "
    system `#{command}`

When I have a replacement string that spans multiple lines it is not properly escaped and appears all on one line in the "file".

What can I do to escape the string properly so sed replaces it with the line breaks intact?

Thanks

script = "s*#{find_what}*#{replace_with}*"
system "sed", "-i", "-e", script, file

This way no escaping is needed.

I presume your replace_with contains strings like this:

replace_with = "this should be\non two lines"

You'll need to escape the \\n from the Ruby interpreter and the shell interpreter so that they can be read by sed(1) . Try this:

replace_with = "this should be \\\\non two lines"

The first doubling: \\\\ to \\\\\\\\ is to get all the backslashes past Ruby. The second doubling: \\ to \\\\ is to get a backslash past the shell. sed ought to see only a single \\ .

A simple test:

$ cat command.rb 
#!/usr/bin/ruby
#
command = "/bin/echo -e \"first line \\\\n second line\""

print `#{command}`
$ ./command.rb 
first line 
 second line
$ 

If you must use sed from within a script, please use the array-based execution method as suggested by Ismael and pguardiario . See the hilarious Process Identifier Preservation Society website for detailed reasons why it is safer to avoid using the shell to start every new process. Better of course would just use the Ruby built-in support for replacement.

将命令分解为多个args可能更有意义,其中只有第一个会被扩展

exec '/bin/echo', '-e', 'first line \n second line'

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM