如何通过JQ从其他文件中读取内容来更新JSON文件?

uttx8gqw  于 2022-10-17  发布在  其他
关注(0)|答案(1)|浏览(149)

我有几个文本文件,每个文件都有一个标题。例如:

echo 'title: hello' > 1.txt
echo 'title: world' > 2.txt
echo 'title: good' > 3.txt

我有一个名为abc.json的JSON文件,它是由如下所示的外壳脚本生成的:

{
  "": [
    {
      "title": "",
      "file": "1"
    },
    {
      "title": "",
      "file": "2"
    },
    {
      "title": "",
      "file": "3"
    }
  ]
}

我想要的是通过相应文本文件中的标题来更新abc.json中的title值,如下所示:

{
  "": [
    {
      "title": "hello",
      "file": "1"
    },
    {
      "title": "world",
      "file": "2"
    },
    {
      "title": "good",
      "file": "3"
    }
  ]
}

文本文件和JSON文件位于相同的目录中,如下所示:

➜  tmp.uFtH6hMC ls
1.txt    2.txt    3.txt    abc.json

非常感谢!

更新要求

抱歉,伙计们。你的所有答案都完全符合上述要求。
但我遗漏了一些重要的详细信息:
1.文本文件的文件名可能包含空格,因此当前目录应如下所示:

➜  $ gfind . -maxdepth 1 -type f -printf '%P\n'
The text file contain one title line and more content.txt
The title identifier in the text file is fixed.txt
The filename of text file may contain space.txt
abc.json

1.文本文件中有一个标题行,其中包含要提取到abc.json中的标题值,即## hello表示需要在abc.json中的title字段中填入“Hello”。标题行可以是文件中的任何一行,看起来像## <title-value>标题标识符##标题行中的第一个空格用一个空格固定并用标题值**表示。因此,文本文件内容可能如下所示:

  • 文本文件包含一个标题行和多个Content.txt*:

## hello world

some more content below...
...
  • 文本文件中的标题标识为fix ed.txt*:

## How are you?

some more content below...
...
  • 文本文件的文件名可以包含空格.txt*:
some pre-content...
...

## I'm fine, thank you.

some more content below...
...

1.更新前,abc.json如下所示:

{
  "": [
    {
      "title": "",
      "file": "The filename of text file may contain space"
    },
    {
      "title": "",
      "file": "The text file contain one title line and more content"
    },
    {
      "title": "",
      "file": "The title identifier in the text file is fixed"
    }
  ]
}

1.更新后的abc.json应该是这样的:

{
  "": [
    {
      "title": "I'm fine, thank you.",
      "file": "The filename of text file may contain space"
    },
    {
      "title": "hello world",
      "file": "The text file contain one title line and more content"
    },
    {
      "title": "How are you?",
      "file": "The title identifier in the text file is fixed"
    }
  ]
}

再次抱歉……谢谢您的耐心和大力帮助!

ruarlubt

ruarlubt1#

您可以使用外壳循环来迭代文件、提取第二列、创建每个数组元素,然后将数组元素流转换为最终对象:

for f in *.txt; do
  cut -d' ' -f2- "$f" | jq -R --arg file "$f" '{title:.,file:($file/"."|first)}';
done | jq -s '{"":.}'

也可以直接删除外壳中的文件扩展名,这会使JQ过滤器稍微简单一些:

for f in *.txt; do
  cut -d' ' -f2- "$f" | jq -R --arg file "${f%.txt}" '{title:.,$file}';
done | jq -s '{"":.}'

cut提取标题值,如果文件的结构不同,则必须对其进行调整,例如使用grep、sed或awk来提取标题,然后将其提供给JQ。

相关问题