使用bash查找和编辑Json文件

时间:2023-01-14 19:26:49

I have multiple files in the following format with different categories like:

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

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

Now I want to append all the files flags whose category is video with string d. So my final file should look like the file below:

现在我想要添加所有的文件标志,它们的类别是带有字符串d的视频。

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

Now using the following command I am able to find files of my interest, but now I want to work with editing part which I an unable to find as there are 100's of file to edit manually, e.g.

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

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

4 个解决方案

#1


1  

You can do this

你可以这样做

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

This will find all the filnames which contain line with "category": "video", and then add the "d" flag.

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

Details:

细节:

find . -type f 

=> Will get all the filenames in your directory

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

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

=> Will get those filenames which contain the line "category": "video"

=>将获得包含行"category": "video"的文件名

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

=> Will add the "d" letter to the flags:line.

=>将向标志添加“d”字母:line。

#2


0  

"TWEET!!" ... (yellow flag thown to the ground) ... Time Out!

“微博! !”…(落地黄旗)……时间了!

What you have, here, is "a JSON file." You also have, at your #!shebang command, your choice of(!) full-featured programming languages ... with intimate and thoroughly-knowledgeale support for JSON ... with which you can very-speedily write your command-file.

这里有一个“JSON文件”。你也有,在你的#!shebang命令,您选择的(!)全功能编程语言……对JSON的亲密和彻底的知识支持……你可以用它来快速地编写你的命令文件。

Even if it is "theoretically possible" to do this using "bash scripts," this is roughly equivalent to "putting a beautiful stone archway over the front-entrance to a supermarket." Therefore, "waste ye no time" in such an utterly-profitless pursuit. Write a script, using a language that "honest-to-goodness knows about(!) JSON," to decode the contents of the file, then manipulate it (as a data-structure), then re-encode it again.

即使“理论上有可能”使用“bash脚本”实现这一点,这大致相当于“在超市的正门上方放置一个漂亮的石头拱门”。因此,在这种毫无意义的追求中“浪费你的时间”。编写一个脚本,使用一种“诚实地知道(!)”的语言。“对文件内容进行解码,然后对其进行操作(作为数据结构),然后再对其进行重新编码”。

#3


0  

Here is a more appropriate approach using PHP in shell:

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

文件= foo2。json php -r '$file = $_SERVER[" file "];file_get_contents(文件)美元美元arr = json_decode();if($ arr - >类别= =“视频”){ $ arr - >标记[]= " d ";写入文件,美元json_encode(arr)美元);} '

Which will load the file, decode into array, add "d" into flags property only when category is video, then write back to the file in JSON format.

它将加载文件,解码成数组,只在类别为视频时将“d”添加到flags属性,然后以JSON格式写入文件。

To run this for every json file, you can use find command, e.g.

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

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

#4


0  

If the files are in the same format, this command may help (version for a single file):

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

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

or:

或者:

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

which is basically using Ex editor (now part of Vim).

基本上就是使用Ex编辑器(现在是Vim的一部分)。

Explanation:

解释:

  • + - executes Vim command (man ex)
  • + -执行Vim命令(man ex)
  • :/pattern_or_range/cmd - find pattern, if successful execute another Vim commands (:h :/)
  • :/pattern_or_range/cmd -如果成功执行了另一个Vim命令(:h:/)
  • norm kkf]i - executes keystrokes in normal mode

    我-在正常模式下执行击键

    • kk - move cursor up twice
    • kk -移动光标两次。
    • f] - find ]
    • f)-找到)
    • i, "d" - insert , "d"
    • i d插入d
  • -s - silent mode
  • - s -静默模式
  • -cwq - executes wq (write & quit)
  • -cwq -执行wq(写和退出)

For multiple files, use find and -execdir or extend above ex command to:

对于多个文件,使用find和-execdir或扩展上面的ex命令:

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

Where bufdo! executes command for every file, and -cxa saves every file. Add -V1 for extra verbose messages.

bufdo !对每个文件执行命令,-cxa保存每个文件。为额外的详细消息添加-V1。

If flags line is not 2 lines above, then you may perform backward search instead. Or using similar approach to @sps by replacing ] with d.

如果标记行不在上面2行,那么您可以执行反向搜索。或者用类似的方法来代替d。

See also: How to change previous line when the pattern is found? at Vim.SE.

参见:如何在发现模式时更改前面的行?在Vim.SE。

#1


1  

You can do this

你可以这样做

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

This will find all the filnames which contain line with "category": "video", and then add the "d" flag.

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

Details:

细节:

find . -type f 

=> Will get all the filenames in your directory

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

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

=> Will get those filenames which contain the line "category": "video"

=>将获得包含行"category": "video"的文件名

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

=> Will add the "d" letter to the flags:line.

=>将向标志添加“d”字母:line。

#2


0  

"TWEET!!" ... (yellow flag thown to the ground) ... Time Out!

“微博! !”…(落地黄旗)……时间了!

What you have, here, is "a JSON file." You also have, at your #!shebang command, your choice of(!) full-featured programming languages ... with intimate and thoroughly-knowledgeale support for JSON ... with which you can very-speedily write your command-file.

这里有一个“JSON文件”。你也有,在你的#!shebang命令,您选择的(!)全功能编程语言……对JSON的亲密和彻底的知识支持……你可以用它来快速地编写你的命令文件。

Even if it is "theoretically possible" to do this using "bash scripts," this is roughly equivalent to "putting a beautiful stone archway over the front-entrance to a supermarket." Therefore, "waste ye no time" in such an utterly-profitless pursuit. Write a script, using a language that "honest-to-goodness knows about(!) JSON," to decode the contents of the file, then manipulate it (as a data-structure), then re-encode it again.

即使“理论上有可能”使用“bash脚本”实现这一点,这大致相当于“在超市的正门上方放置一个漂亮的石头拱门”。因此,在这种毫无意义的追求中“浪费你的时间”。编写一个脚本,使用一种“诚实地知道(!)”的语言。“对文件内容进行解码,然后对其进行操作(作为数据结构),然后再对其进行重新编码”。

#3


0  

Here is a more appropriate approach using PHP in shell:

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

文件= foo2。json php -r '$file = $_SERVER[" file "];file_get_contents(文件)美元美元arr = json_decode();if($ arr - >类别= =“视频”){ $ arr - >标记[]= " d ";写入文件,美元json_encode(arr)美元);} '

Which will load the file, decode into array, add "d" into flags property only when category is video, then write back to the file in JSON format.

它将加载文件,解码成数组,只在类别为视频时将“d”添加到flags属性,然后以JSON格式写入文件。

To run this for every json file, you can use find command, e.g.

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

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

#4


0  

If the files are in the same format, this command may help (version for a single file):

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

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

or:

或者:

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

which is basically using Ex editor (now part of Vim).

基本上就是使用Ex编辑器(现在是Vim的一部分)。

Explanation:

解释:

  • + - executes Vim command (man ex)
  • + -执行Vim命令(man ex)
  • :/pattern_or_range/cmd - find pattern, if successful execute another Vim commands (:h :/)
  • :/pattern_or_range/cmd -如果成功执行了另一个Vim命令(:h:/)
  • norm kkf]i - executes keystrokes in normal mode

    我-在正常模式下执行击键

    • kk - move cursor up twice
    • kk -移动光标两次。
    • f] - find ]
    • f)-找到)
    • i, "d" - insert , "d"
    • i d插入d
  • -s - silent mode
  • - s -静默模式
  • -cwq - executes wq (write & quit)
  • -cwq -执行wq(写和退出)

For multiple files, use find and -execdir or extend above ex command to:

对于多个文件,使用find和-execdir或扩展上面的ex命令:

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

Where bufdo! executes command for every file, and -cxa saves every file. Add -V1 for extra verbose messages.

bufdo !对每个文件执行命令,-cxa保存每个文件。为额外的详细消息添加-V1。

If flags line is not 2 lines above, then you may perform backward search instead. Or using similar approach to @sps by replacing ] with d.

如果标记行不在上面2行,那么您可以执行反向搜索。或者用类似的方法来代替d。

See also: How to change previous line when the pattern is found? at Vim.SE.

参见:如何在发现模式时更改前面的行?在Vim.SE。

相关文章