【问题标题】:Find and edit a Json file using bash使用 bash 查找和编辑 Json 文件
【发布时间】:2016-11-11 14:35:30
【问题描述】:

我有多个不同类别的文件,格式如下:

{
    "id": 1,
    "flags": ["a", "b", "c"],
    "name": "test",
    "category": "video",
    "notes": ""
}

现在我想用字符串d 附加所有类别为video 的文件标志。所以我的最终文件应该如下所示:

{
    "id": 1,
    "flags": ["a", "b", "c", "d"],
    "name": "test",
    "category": "video",
    "notes": ""
}

现在使用以下命令我可以找到我感兴趣的文件,但现在我想使用我无法找到的编辑部分,因为有 100 个文件需要手动编辑,例如

find . - name * | xargs grep "\"category\": \"video\"" | awk '{print $1}' | sed 's/://g'

【问题讨论】:

  • 好像是Video中的大写V造成的?所以它应该是这样的"\"category\": \"video\""
  • @SWLim 抱歉,打错字了,是'v'。我编写的命令可以正常获取所有类别为'video' 的文件。现在我想要一个命令来编辑我的 json 文件标志。

标签: json regex bash unix sed


【解决方案1】:

你可以这样做

find . -type f | xargs grep -l '"category": "video"' | xargs  sed -i -e '/flags/ s/]/, "d"]/'

这将找到所有包含"category": "video" 行的文件名,然后添加"d" 标志。

详情:

find . -type f 

=> 将获取您目录中的所有文件名

xargs grep -l '"category": "video"'

=> 将获取那些包含"category": "video" 行的文件名

xargs  sed -i -e '/flags/ s/]/, "d"]/'

=> 将"d" 字母添加到flags: 行。

【讨论】:

  • 这就是我一直在寻找的答案
【解决方案2】:

如果文件格式相同,此命令可能会有所帮助(单个文件的版本):

ex +':/category.*video/norm kkf]i, "d"' -scwq file1.json

或:

ex +':/flags/,/category/s/"c"/"c", "d"/' -scwq file1.json

基本上是使用Ex editor(现在是 Vim 的一部分)。

解释:

  • + - 执行 Vim 命令 (man ex)
  • :/pattern_or_range/cmd - 查找模式,如果成功执行另一个 Vim 命令 (:h :/)
  • norm kkf]i - 在正常模式下执行击键

    • kk - 将光标向上移动两次
    • f] - 找到]
    • i, "d" - 插入 , "d"
  • -s - 静音模式
  • -cwq - 执行 wq(写入并退出)

对于多个文件,使用find-execdir 或将ex 命令扩展到:

ex +'bufdo!:/category.*video/norm kkf]i, "d"' -scxa *.json

bufdo! 对每个文件执行命令,-cxa 保存每个文件。添加 -V1 以获取更多详细信息。

如果flags 行不在上面两行,那么您可以改为执行向后搜索。或者使用与@sps 类似的方法,将] 替换为d

另请参阅:How to change previous line when the pattern is found?Vim.SE

【讨论】:

  • @NabaChinde 它适用于您的示例文件,也许您的格式不同?
【解决方案3】:

“TWEET!!” ... (黄旗被扔到地上) ... 超时!

在这里,您拥有的是“一个 JSON 文件”。你有,在你的#!shebang命令,你选择(!) 功能齐全的编程语言 ...亲密而彻底- 对 JSON 的知识支持......您可以使用它非常快速地编写您的命令文件。

即使使用“bash 脚本”“理论上可行”,这也大致相当于“在超市的正门上放置一个漂亮的石拱门”。因此,“浪费你没有时间”在这种完全无益的追求中。编写一个脚本,使用“诚实的知道(!) JSON”的语言来解码文件的内容,然后操作它(作为数据结构) , 然后重新编码。

【讨论】:

  • 我确实尝试过使用编程语言,但是每当我编辑 JSON 文件时,我需要序列化,这也是一个令人头疼的问题。
  • 我不明白你所说的“需要序列化(d)”是什么意思。据我所知,唯一方式可靠地“编辑” JSON 文件就是解析它,更改内存中的数据结构,然后重写文件的全部内容。使用真正的编程语言。与实际数据一起使用时,格式存在许多细微之处,并且将其与“sed”或某些编辑器结合使用极有可能破坏文件,导致任何人或任何事物都无法读取它。
【解决方案4】:

这是在 shell 中使用 PHP 的更合适的方法:

FILE=foo2.json php -r '$file = $_SERVER["FILE"]; $arr = json_decode(file_get_contents($file)); if ($arr->category == "video") { $arr->flags[] = "d"; file_put_contents($file,json_encode($arr)); }'

这将加载文件,解码成数组,仅当类别为视频时将“d”添加到flags属性中,然后以JSON格式写回文件。

要为每个 json 文件运行这个,你可以使用 find 命令,例如

find . -name "*.json" -print0 | while IFS= read -r -d '' file; do
    FILE=$file
    # run above PHP command in here
done

【讨论】:

    【解决方案5】:

    使用jq:

    find . -type f | xargs cat | jq 'select(.category=="video") | .flags |= . + ["d"]'
    

    解释:

    jq 'select(.category=="video") | .flags |= . + ["d"]'
       # select(.category=="video") =>  filters by category field
       # .flags |= . + ["d"] => Updates the flags array
    

    【讨论】:

      猜你喜欢
      • 2020-12-14
      • 2020-09-09
      • 2011-05-26
      • 2017-05-04
      • 2016-01-18
      • 1970-01-01
      • 2017-08-01
      • 2021-09-04
      • 2015-02-27
      相关资源
      最近更新 更多