首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >sed在匹配单行字符串后追加多行字符串。

sed在匹配单行字符串后追加多行字符串。
EN

Stack Overflow用户
提问于 2015-12-16 22:44:21
回答 3查看 694关注 0票数 2

如果可能的话,我想用sed来解决这个问题。以下是我的情况:

我有一个多行字符串,它将通过外部方式提供给sed --可能是木偶shell、exec或bash脚本。该字符串看起来如下:

代码语言:javascript
复制
$string = 'blah blah blah\nblahblah\nblah blah blah\n\n'

我想运行一个sed命令,在找到匹配后追加这个字符串-

代码语言:javascript
复制
sed -i "/^\[org\/gnome\/login-screen\]/a banner-message-text='$string'" /etc/dconf/db/gdm.d/00-mybanner

问题在于,sed\n字符解释为换行符。注意,我意识到在sed命令中声明sed变量的方式可能会因其执行方式而有所不同,但即使在命令行上手动输入字符串也会产生多行输出。因此,该文件最后看起来如下:

代码语言:javascript
复制
[org/gnome/login-screen]
banner-message-text='blah blah blah
blablah
blah blah blah

'
banner-message-enable=true

这会导致dconf update抛出错误。我希望这份文件看起来像:

代码语言:javascript
复制
[org/gnome/login-screen]
banner-message-text='blah blah blah\nblablah\nblah blah blah\n\n'
banner-message-enable=true

但是我似乎不能让sed停止解释\n。谢谢!

编辑-使用木偶实现的解决方案(@tom-fenech)的完整上下文:

代码语言:javascript
复制
  $banner_msg = 'blah blah blah\nblahblah\nblah blah blah\n\n'

  $comply_cmd = "find /etc/dconf/db/gdm.d -maxdepth 1 -type f -print0 | xargs -0 sed -i '/^banner-message-text=/d' || /bin/true && \
    (grep -q \"^\[org/gnome/login-screen\]\" /etc/dconf/db/gdm.d/99-banner && \
    sed -i \"/^\[org\/gnome\/login-screen\]/a banner-message-text='\$(printf '%q' \"${banner_msg}\")'\" /etc/dconf/db/gdm.d/99-banner) || \
    (echo -e \"\n\[org/gnome/login-screen]\" >> /etc/dconf/db/gdm.d/99-banner && \
    echo \"banner-message-text='${banner_msg}'\" >> /etc/dconf/db/gdm.d/99-banner)"

  $unless_cmd = "grep -q \"^banner-message-text='\$(printf '%q' \"${banner_msg}\")'$\" /etc/dconf/db/gdm.d/99-banner"

  exec { 'gdm-banner-msg':
    path     => '/sbin:/bin:/usr/sbin:/usr/bin',
    umask    => '022',
    provider => shell,
    command  => $comply_cmd,
    unless   => $unless_cmd,
    notify   => Exec['dconf-update'],
  }

谢谢大家!

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2015-12-16 23:54:54

printf%q格式说明符一起使用。这能帮你解决逃跑的问题:

代码语言:javascript
复制
$ echo "$string"
blah blah blah\nblahblah\nblah blah blah\n\n
$ printf '%q' "$string"
blah\ blah\ blah\\nblahblah\\nblah\ blah\ blah\\n\\n

来自man bash

%q使printf以可以作为shell输入重用的格式输出相应的参数。

这意味着空格也是反斜杠--转义,但这并没有坏处。

测试一下:

代码语言:javascript
复制
$ cat file
[org/gnome/login-screen]
$ sed "/^\[org\/gnome\/login-screen\]/a banner-message-text='$(printf '%q' "$string")'" file
[org/gnome/login-screen]
banner-message-text='blah blah blah\nblahblah\nblah blah blah\n\n'
票数 3
EN

Stack Overflow用户

发布于 2015-12-16 23:50:51

你需要避开你的反斜杠:

代码语言:javascript
复制
$ string='blah blah blah\\nblahblah\\nblah blah blah\\n\\n'
$ echo $string
blah blah blah\\nblahblah\\nblah blah blah\\n\\n
$ cat foo.txt
foo
baz
test

$ sed -i "/^foo/a bar='$string'" foo.txt 
$ cat foo.txt 
foo
bar='blah blah blah\nblahblah\nblah blah blah\n\n'
baz
test

$
票数 1
EN

Stack Overflow用户

发布于 2015-12-17 00:06:52

准备初始配置文件:

代码语言:javascript
复制
echo -e "[org/gnome/login-screen]\nbanner-message-enable=true"> /etc/dconf/db/gdm.d/00-mybanner
cat /etc/dconf/db/gdm.d/00-mybanner

[org/gnome/login-screen]
banner-message-enable=true

插入新的标题消息而不解释\n字符:

代码语言:javascript
复制
string='blah blah blah\\nblahblah\\nblah blah blah\\n\\n'; sed -i "/^\[org\/gnome\/login-screen\]/a banner-message-text=\'$string\'" /etc/dconf/db/gdm.d/00-mybanner

见结果:

代码语言:javascript
复制
cat /etc/dconf/db/gdm.d/00-mybanner

[org/gnome/login-screen]
banner-message-text='blah blah blah\nblahblah\nblah blah blah\n\n'
banner-message-enable=true

关键是:在字符串中的每个 \n之前加一个额外的斜杠。这将阻止sed解释\n字符。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34323582

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档