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

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

이 줄에서 "name" 값을 가져와야 합니다.

"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

이는 입력을 받아 "레코드"를 분할합니다(보통)을 에 기록한 ,다음 모든 레코드를 의 필드에 기록하고 :레코드당 두 ​​개의 필드를 남겨둡니다. 첫 번째 필드인 경우in "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).

관련 정보