【问题标题】:sed(1): prepend a linesed(1):添加一行
【发布时间】:2012-11-13 12:50:05
【问题描述】:

我在一个文件中有以下文本结构:

"require": {
    "php": ">=5.3.3",
    "symfony/symfony": "2.1.*",
    "jms/di-extra-bundle": "1.1.*"
},

我想补充

, "friendsofsymfony/user-bundle": "*"

在“}”之前,使用 sed(1)。

我还必须考虑到最后一行结尾可能有也可能没有逗号。

我尝试了很多东西;

sed '/require/,/\},/ { /[^,]$/ i//&,\n        '\'something\''/ }' composer.json;

但我无法让它工作。

感谢任何帮助。

【问题讨论】:

  • 你需要使用sed吗?一般来说,解码 JSON、添加密钥并重新编码(例如使用 PHP)可能更安全。
  • 也许使用 PHP 脚本会更容易做到这一点?我的主要目标是调用某种脚本来编辑这个文件(添加一个 JSON 元素)。

标签: shell scripting sed


【解决方案1】:

这很难用 sed 稳健地完成,您应该使用适当的 JSON 库。

但是要使用 GNU sed 做你想做的事,你可以做这样的事情(这里不检查结尾逗号):

sed '/require/,/},/ s/},/, "friendsofsymfony\/user-bundle": "\*"\n&/ 

要检查结束逗号,您需要进行更多解析:

parse.sed

/^[ \t]*"require/ {                       # when 'require' found
  : a
  N                                       # run through pairwise
  /\n[\t ]*\},/! { P; s/[^\n]+\n//; ba }  # lines until '},' is found
  /,\n/! s/\n/,&/                         # append comma if not present
  s/\n([\t ]*)},/\n\1\1"friendsofsymfony\/user-bundle": "\*"&/
}

运行:

sed -rf parse.sed infile

在提供的示例文件上运行时 parse.sed 的输出摘录:

[...]

"require": {
    "php": ">=5.3.3",
    "symfony/symfony": "2.2.*",
    "doctrine/orm": ">=2.2.3,<2.4-dev",
    "doctrine/doctrine-bundle": "1.0.*",
    "twig/extensions": "1.0.*",
    "symfony/assetic-bundle": "2.1.*",
    "symfony/swiftmailer-bundle": "2.1.*",
    "symfony/monolog-bundle": "2.1.*",
    "sensio/distribution-bundle": "2.2.*",
    "sensio/framework-extra-bundle": "2.2.*",
    "sensio/generator-bundle": "2.2.*",
    "jms/security-extra-bundle": "1.3.*",
    "jms/di-extra-bundle": "1.2.*",
    "friendsofsymfony/user-bundle": "*"
},

[...]

【讨论】:

    【解决方案2】:

    使用i 命令插入。要插入的字符串末尾需要换行符:

    sed '/require/,/},/{/^},/i, "friendsofsymfony/user-bundle": "*"
    }'
    

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-10-14
    • 1970-01-01
    • 1970-01-01
    • 2012-04-30
    • 1970-01-01
    • 1970-01-01
    • 2016-11-06
    • 1970-01-01
    相关资源
    最近更新 更多