문자열 필드를 jq의 배열로 분할하시겠습니까?

문자열 필드를 jq의 배열로 분할하시겠습니까?

다음과 같이 컬에서 반환된 JSON 배열이 있습니다.

[
 {
   "title": "Some Title",
   "tags":"tagA tag-B tagC"
 },
 {
   "title": "Some Title 2",
   "tags":"tagA tagC"
 },
 ...
]

그걸로 변환하고 싶은데...

[
 {
   "title": "Some Title",
   "tags":["tagA",
           "tag-B",
           "tagC"]
 },
 {
   "title": "Some Title 2",
   "tags":["tagA", 
           "tagC"]
 },
 ...
]

지금까지 나는 다음을 가지고 있습니다 :

(map(select(.tags!=null)) | map(.tags | split(" "))) as $tags | $tags

이것은 나에게 다음과 같은 것을 제공하는 것 같습니다:

     [
      [
       "tagA",
       "tag-B",
       "tagC"
      ],
      [
       "tagA", 
       "tagC"
      ]
     ]

.tags하지만 원래 객체의 원래 값을 가진 배열로 제공하는 출력으로 다시 엮을 수는 없는 것 같습니다 ...

답변1

당신은 상황을 실제보다 훨씬 더 복잡하게 만들고 있습니다. 그냥 사용 map()하고 |=:

jq 'map(.tags |= split(" "))' file.json

편집하다:

다음 없이 항목을 처리하려는 경우 tags:

jq 'map(try(.tags |= split(" ")))' file.json

또는 모든 항목을 변경하지 않고 유지하려는 경우 tags:

jq 'map(try(.tags |= split(" ")) // .)' file.json

결과:

[
  {
    "tags": [
      "tagA",
      "tag-B",
      "tagC"
    ],
    "title": "Some Title"
  },
  {
    "tags": [
      "tagA",
      "tagC"
    ],
    "title": "Some Title 2"
  }
]

답변2

다음을 시도해 볼 수 있습니다 sed.

다음 코드는 sed의 GNU 버전을 사용합니다(POSIX 호환 방식으로 작성될 수도 있음).

sed -e '
   /[{]/,/[}]/!b
   /"tags":/!b

   h;s/"tags":/&\n/;s/\n.*/ /;s/./ /g;x

   s/"tags":/&\n/
   :a
   s/\(\n.*\)\([^"]\) \([^"]\)/\1\2","\3/;ta

   y/\n/[/;s/$/]/;G

   :b
   s/","\(.*\)\(\n.*\)/",\2"\1\2/;tb
   s/\(.*\)\n.*/\1/

' yourjsonfile

피복재

  1. {다음 행의 범위를 선택합니다 }.
  2. "tags"Line 선택한 범위 내의 라인을 확대합니다 .
  3. 주어진 라벨의 중첩 공간을 계산하고 보관하십시오.
  4. 루프의 큰따옴표 데이터:a
  5. ,루프 뒤에 중첩 공백 삽입:b
  6. 패턴 공간에서 마지막 개행 문자 뒤의 모든 항목을 제거하고 인쇄합니다.

결과

[
 {
   "title": "Some Title",
   "tags":["tagA",
           "tag-B",
           "tagC"]
 },
 {
   "title": "Some Title 2",
   "tags":["tagA",
           "tagC"]
 },
 ...
]

관련 정보