【问题标题】:Bash script iterate through file and delete block of text using sedBash 脚本遍历文件并使用 sed 删除文本块
【发布时间】:2018-10-03 08:45:49
【问题描述】:

我有一个包含以下内容的 JSON 文件:

[
    {
        "url" : "www.google.com",
        "valid_from" : "            Jul 31 10:16:13 2017 GMT",
        "valid_till" : "            Jul 31 10:16:13 2019 GMT",
        "validity" : "Valid",
        "days" : "464"
    },
    {
        "url" : "www.youtube.com",
        "valid_from" : "            Apr  9 12:12:17 2017 GMT",
        "valid_till" : "            Apr  9 12:12:17 2019 GMT",
        "validity" : "Valid",
        "days" : "351"
    }
]

我想通过传递与要删除的块相对应的 url 参数来删除 JSON 块。 我有一个脚本cert-check-script-delete.sh,其中包含以下代码:

line_num=1

cat certs.json >> certs-new.json

while read p; do  # Iterate through each line in certs.json
    if [[ $p == *"$1"* ]];   # Check if current line contains argument
    then
        sed -i "${line_num-1}d" certs-new.json  # {
        sed -i "${line_num}d"   certs-new.json  # Url
        sed -i "${line_num+1}d" certs-new.json  # Valid from
        sed -i "${line_num+2}d" certs-new.json  # Valid till
        sed -i "${line_num+3}d" certs-new.json  # Validity
        sed -i "${line_num+4}d" certs-new.json  # Days
        sed -i "${line_num+5}d" certs-new.json  # }
        break
    fi
    ((line_num++))
done <certs.json

mv certs-new.json certs.json

在使用参数www.youtube.com 运行我的脚本后,我得到了奇怪的行为,它似乎只是在删除随机行:

    {
        "valid_from" : "            Jul 31 10:16:13 2017 GMT",
        "validity" : "Valid",
    {
        "valid_till" : "            Apr  9 12:12:17 2019 GMT",
        "validity" : "Valid",
        "days" : "351"
    }
]

我知道我应该使用 jq 来插入/删除 JSON,但我无法在工作中安装它,所以请不要只评论说使用 jq
任何帮助表示赞赏!

【问题讨论】:

  • 不是js,而是jq,您为什么不想使用它?
  • 你至少可以使用perl
  • 你可以稍微改变你的逻辑。每行读取一行并将这些行复制到输出文件中。当您点击“{”时,停止复制行。然后验证下一行以查看它是否与您的 URL 匹配。有吗?停止复制,直到您点击“}”。否则,继续在输出文件中复制。然后还有, 需要考虑...这是可行的,但实际上有更简单的解决方案(语言和/或工具)。
  • 是的,为什么不使用 json 解析器呢?使用jq,可能类似于jq -r 'map(select(."url" != "www.youtube.com"))'
  • @Inian 我在工作中编写这个应用程序,不允许下载和运行 jq .exe。有没有办法通过 Git Bash/cmd 安装它?

标签: json bash shell sed


【解决方案1】:

你可以这样做:-

 sed -i '/www.youtube.com/I,+6 d;$!N;/www.youtube.com/!P;D' certs-new.json

如果您的搜索字符串已作为命令行参数提供,请使用类似

sed -i '/'$1'/I,+6 d;$!N;/'$1'/!P;D' certs-new.json

它将如何工作,首先它将搜索模式www.youtube.com并删除模式下方的6行,sed命令的第二部分将搜索模式www.youtube.com并删除模式行及其上方的一行。

在您的示例中,输出将是:-

[
{
    "url" : "www.google.com",
    "valid_from" : "            Jul 31 10:16:13 2017 GMT",
    "valid_till" : "            Jul 31 10:16:13 2019 GMT",
    "validity" : "Valid",
    "days" : "464"
},
]

【讨论】:

  • 谢谢,这行得通,但是当我尝试用参数变量替换命令中的 url 时,它什么也没做。我试过用$1{$1}"$1"替换命令中的www.youtube.com
  • 使用双引号,如 sed -i "/$1/I,+6 d;$!N;/$1/!P;D"
  • 谢谢!非常好的 1 线解决方案。只是一个问题,当我在 Youtube 上执行此操作时效果很好,但是当我在 Google 上执行此操作时,它会删除 Youtube 的左括号,知道为什么吗?
  • 可能有些空间使用+5 d 而不是+6 d 并检查
  • 嗨,当文件中有超过 1 个 JSON 条目时,这可以正常工作,但是当只有 1 个时,它只留下最后 2 个括号 }] 而不是第一个和最后一个括号 [],任何想法为什么会发生这种情况?
猜你喜欢
  • 1970-01-01
  • 2010-09-25
  • 1970-01-01
  • 2016-02-08
  • 1970-01-01
  • 2011-10-20
  • 1970-01-01
  • 2021-05-31
  • 1970-01-01
相关资源
最近更新 更多