특정 단어 뒤에 값을 가져와야 합니다.

특정 단어 뒤에 값을 가져와야 합니다.

이 행에서 "이름" 값을 가져와야 합니다.

"snapshots": [{"name":"sLVZt","user":"comment","current":"n","created":"2015-03-11 05:28:02"},{"name":"ubg9x","user":"test2",{"name":"lo3Qp","user":"test3","current":"y","created":"2015-03-11 06:02:46"}]}

나는 출력이 다음과 같기를 원합니다.

sLVZt
ubg9x
lo3Qp

답변1

JSON 문서가 유효하다고 가정합니다.

{"snapshots":[{"name":"sLVZt","user":"comment","current":"n","created":"2015-03-11 05:28:02"},{"name":"ubg9x","user":"test2"},{"name":"lo3Qp","user":"test3","current":"y","created":"2015-03-11 06:02:46"}]}

또는 (비데이터 공백은 형식에 독립적이기 때문에)

{
  "snapshots": [
    {
      "name": "sLVZt",
      "user": "comment",
      "current": "n",
      "created": "2015-03-11 05:28:02"
    },
    {
      "name": "ubg9x",
      "user": "test2"
    },
    {
      "name": "lo3Qp",
      "user": "test3",
      "current": "y",
      "created": "2015-03-11 06:02:46"
    }
  ]
}

jq그런 다음 다음과 같이 사용하십시오.

$ jq -r '.snapshots[].name' file.json
sLVZt
ubg9x
lo3Qp

name그러면 배열의 각 요소에 있는 키 값이 추출됩니다 snapshots.

다양한 방법으로 다른 키의 값을 기반으로 결과를 쉽게 필터링할 수도 있습니다.

$ jq -r '.snapshots[] | select(.current == "y").name' file.json
lo3Qp
$ jq -r '.snapshots[] | select(.current != "n").name' file.json
ubg9x
lo3Qp

답변2

Linux를 사용 중이거나 GNU에 액세스할 수 있는 경우 grep다음을 수행할 수 있습니다.

$ grep -oP '"name":"\K[^"]+' file 
sLVZt
ubg9x
lo3Qp

또는 Perl에서는:

$ perl -lne 'print join "\n", /"name":"([^"]+)/g' file 
sLVZt
ubg9x
lo3Qp

답변3

이 시도,

 sed 's/,/\n/g' file | awk -F '"' '$2~/name/ {print $(NF-1)}'

sLVZt
ubg9x
lo3Qp

답변4

순수 awk기반 솔루션은 다음과 같습니다.

awk -F':' -v RS=',' '$1 ~ /"name"$/ {print $2}' file

이는 입력을 받아 "레코드"를 분할합니다(일반적으로철사) 를 ,선택한 다음 모든 레코드를 의 필드에 배치하고 :각 레코드에 대해 두 개의 필드를 남겨 둡니다. 첫 번째 필드인 경우마치다"name"(선행 대괄호/중괄호에 대한 설명) 에서 두 번째 필드인 를 인쇄합니다 :.

지원하는 큰따옴표를 제거하려면 다음을 사용할 수 있습니다.

awk -F':' -v RS=',' '$1 ~ /"name"$/ {gsub("\"","",$2); print $2}' file

고쳐 쓰다

수정된 예제 입력에는 선도 "snapshots":포함되어 있지만 "불균형" 방식으로 포함되어 있으므로 :더 이상 작동하지 않습니다. 내 대답은 "순수한 기반"이라고 말하므로 awk가능한 유일한 적응은 더 복잡하며 다음과 같습니다.

awk '{n=patsplit($0,field,"\"[^\"]*\":\"[^\"]*\""); for (i=1;i<=n;i++) {split(field[i],elem,":"); if (elem[1]=="\"name\"") print elem[2];};}' file

분명히 이것은 grep기반 접근 방식보다 훨씬 덜 우아하고 이식성이 떨어집니다( mawk예: 에 적합하지 않음).

관련 정보