Sed 从 Ruby 内部逃逸

发布于 2024-12-21 22:23:18 字数 254 浏览 0 评论 0 原文

我有一个 Ruby 脚本,如下调用“sed”:

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

当我有一个跨越多行的替换字符串时,它没有正确转义,并且全部出现在“文件”中的一行上。

我该怎么做才能正确转义字符串,以便 sed 将其替换为完整的换行符?

谢谢

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

变身佩奇 2024-12-28 22:23:18
script = "s*#{find_what}*#{replace_with}*"
system "sed", "-i", "-e", script, file

这样就不需要转义了。

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

This way no escaping is needed.

万劫不复 2024-12-28 22:23:18

我假设您的 replace_with 包含这样的字符串:

replace_with = "this should be\non two lines"

您需要从 Ruby 解释器和\n > shell 解释器,以便 sed(1) 可以读取它们。试试这个:

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

第一次加倍: \\\\\\ 是为了获取 Ruby 后面的所有反斜杠。第二次加倍: \\\ 是为了在 shell 后面添加一个反斜杠。 sed 应该只能看到一个 \

一个简单的测试:

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

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

如果您必须在脚本中使用 sed,请使用 pguardiario。请参阅热闹的进程标识符保护协会网站了解避免使用 shell 启动每个新进程更安全的详细原因。当然更好的是使用 Ruby 内置的替换支持。

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.

生生漫 2024-12-28 22:23:18

将命令分解为多个参数可能更有意义,其中只有第一个 将得到扩展

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

It might make more sense to break up the command into mulitple args, of which only the first will get expanded

exec '/bin/echo', '-e', 'first line \n second line'
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文