linux - 将值从 bash for 循环转换为 json 对象

标签 linux bash unix

下面是我对 txt 文件名进行排序的 for 循环片段。然后我试图将结果保存在 json 格式的文件中。但是,它会导致不符合要求的 json 格式。我如何将 for 循环中的值转换为所需的 json 格式?

dir="myfiles/test/"

prefix=""
echo "[" >> test.json
for dir in "${array[@]}"; do
        #reverse the result of comparisons
        file=$(find "$dir" -maxdepth 1 -type f -iname '*.txt' | awk "NR==$i")
        [[ -n $file ]] && 
                printf '%b{ "filepath": "%s" }' $prefix "$file" >> test.json
        prefix=",\n"
done
echo
echo "]" >> test.json

当前输出

[
    { "filepath" : "myfiles/test/sdfsd.txt" },
    { "filepath" : "myfiles/test/piids.txt" },
    { "filepath" : "myfiles/test/saaad.txt" },
    { "filepath" : "myfiles/test/smmnu.txt" },
]

期望的输出

[
    [
        { "filepath" : "myfiles/test/sdfsd.txt" }
    ],
    [
        { "filepath" : "myfiles/test/piids.txt" }
    ],
    [
        { "filepath" : "myfiles/test/saaad.txt" }
    ],
    [
        { "filepath" : "myfiles/test/smmnu.txt" }
    ]
]

也允许

[
    [
        { "filepath" : "myfiles/test/sdfsd.txt" },
        { "filepath" : "myfiles/test/sdfsd2.txt" }
    ],
    [
        { "filepath" : "myfiles/test/piids.txt" },
        { "filepath" : "myfiles/test/piids2.txt" }
    ],
    [
        { "filepath" : "myfiles/test/saaad.txt" }
    ],
    [
        { "filepath" : "myfiles/test/smmnu.txt" }
    ]
]

最佳答案

结合使用jq 实现你的目标。首先,我们在句法上将不需要的输出转换为正确的格式。然后我们使用 jq 格式化它。

我们使用以下 awk 脚本:

{
    # extract names of files (to see if they are equal
    # besides a numerical suffix).
    name1 = line
    name2 = $0
    sub(/"[^"]*$/, "", name1)
    sub(/"[^"]*$/, "", name2)
    sub(/.*\//, "", name1)
    sub(/.*\//, "", name2)
    sub(/\....$/, "", name1)
    sub(/\....$/, "", name2)
    sub(/[0-9]*$/, "", name1)
    sub(/[0-9]*$/, "", name2)
    # add array symbols to the line
    # if last item was closed by a ']' add '[' to beginning
    if (closed)
        sub(/{/, "[{", line)
    # if names are equal, same array
    if (name1 != name2) {
        sub(/},/, "}],", line)
        closed = 1
    } else
        closed = ""
    # if last line, consisting of simply a '['
    if ($0 ~ /^]$/)
        # remove extra comma at end of line
        sub(/,$/, "", line)
    # if line is set, print line
    if (line)
        print line
    # set current line to line variable
    line = $0
}

这会产生格式错误的输出:

$ cat file 
[
    { "filepath" : "myfiles/test/sdfsd.txt" },
    { "filepath" : "myfiles/test/piids.txt" },
    { "filepath" : "myfiles/test/saaad.txt" },
    { "filepath" : "myfiles/test/smmnu.txt" },
]
$ awk -f script.awk file
[
    [{ "filepath" : "myfiles/test/sdfsd.txt" }],
    [{ "filepath" : "myfiles/test/piids.txt" }],
    [{ "filepath" : "myfiles/test/saaad.txt" }],
    [{ "filepath" : "myfiles/test/smmnu.txt" }]
]

我们现在可以使用 jq 格式化:

$ awk -f script.awk file | jq .
[
  [
    {
      "filepath": "myfiles/test/sdfsd.txt"
    }
  ],
  [
    {
      "filepath": "myfiles/test/piids.txt"
    }
  ],
  [
    {
      "filepath": "myfiles/test/saaad.txt"
    }
  ],
  [
    {
      "filepath": "myfiles/test/smmnu.txt"
    }
  ]
]

请注意,这会处理几乎相同的文件,因为它们仅在数字后缀上有所不同。示例:

$ cat file 
[
    { "filepath" : "myfiles/test/sdfsd.txt" },
    { "filepath" : "myfiles/test/sdfsd2.txt" },
    { "filepath" : "myfiles/test/piids.txt" },
    { "filepath" : "myfiles/test/saaad.txt" },
    { "filepath" : "myfiles/test/smmnu.txt" },
]
$ awk -f script.awk file | jq .
[
  [
    {
      "filepath": "myfiles/test/sdfsd.txt"
    },
    {
      "filepath": "myfiles/test/sdfsd2.txt"
    }
  ],
  [
    {
      "filepath": "myfiles/test/piids.txt"
    }
  ],
  [
    {
      "filepath": "myfiles/test/saaad.txt"
    }
  ],
  [
    {
      "filepath": "myfiles/test/smmnu.txt"
    }
  ]
]

关于linux - 将值从 bash for 循环转换为 json 对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31226406/

相关文章:

python - RTSP 流和 OpenCV (Python)

linux - 按名称查找文件夹然后复制文件

linux - Bash 脚本 : how to add a section to a config file?

linux - 将文件名作为脚本中的密码值

linux - 如何将包含空格的变量分配给 KSH 中的另一个变量

linux - 适用于 Linux 的 WPP 跟踪

C 中基本 TCP 客户端服务器编程中的连接错误

linux - 空输入字符垃圾邮件 Linux tty

bash - 搜索文件中的字符串并通过 Shell 脚本从该文件中删除它

bash - Bicep 文件中的部署后 bash 脚本不执行