使用bash查找和编辑Json文件

时间:2016-07-08 23:08:59

标签: json regex bash unix sed

我有以下格式的多个文件,其中包含不同的类别:

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

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

{
    "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'

5 个答案:

答案 0 :(得分:1)

你可以这样做

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

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

<强>详细信息:

find . -type f 

=&GT;将获取目录中的所有文件名

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

=&GT;将获取包含行"category": "video"

的文件名
xargs  sed -i -e '/flags/ s/]/, "d"]/'

=&GT;将"d"字母添加到flags:行。

答案 1 :(得分:0)

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

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行不是上面两行,那么您可以改为执行向后搜索。或者通过将]替换为d来使用@sps的类似方法。

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

答案 2 :(得分:0)

&#34; TWEET !!&#34; ... (黄旗落地) ... < strong>超时!

您拥有的是&#34; JSON文件。&#34;您在您的#!shebang命令中选择了(!) 功能齐全的编程语言 ... ...和JSON的全面知识支持...您可以非常快速地编写命令文件。

即使它在理论上是可能的&#34;使用&#34; bash脚本执行此操作,&#34;这大致相当于&#34;在超市的正门上放置一个漂亮的石拱门。&#34;因此, &#34;浪费 ye 没时间&#34;在这样一个完全无利可图的追求。编写一个脚本,使用&#34;诚实 - 善良了解(!) JSON,&#34;解码文件的内容,然后操作它(作为数据结构),然后再重新编码。

答案 3 :(得分:0)

这是在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)); }'

将加载文件,解码到数组中,添加&#34; d&#34;仅当类别为视频时才进入 flags 属性,然后以JSON格式写回文件。

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

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

答案 4 :(得分:0)

使用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