bash 스크립트에서 문자열 구문 분석

다른 답변을 검토했지만이를 수행하는 방법에 대한 적절한 설명을 얻지 못했습니다.

I id="{"name":"john"}"와 같은 id라는 문자열 변수가 있습니다.이 문자열에서 2 개의 변수를 어떻게 얻을 수 있습니까?

key="name" value="john" 

bash에서 문자열 구문 분석을 이해하고 싶으므로 자세한 설명을 주시면 감사하겠습니다.

지금까지 중괄호 문자열에서-

id="$( echo "${id}" | tr -d {} )" 

"를 다음과 같이 포함 할 수 없습니다. 오류가 발생합니다. 또한 배열을 얻기 위해 마지막에 id.split(":")와 같은 것을 찾습니다.

댓글

  • 너무 늦기 전에 '이 전술 / 트랙에 대해 경고 할 수 있나요? 거기에 json 또는 기타 구조화 된 데이터가있는 것 같습니다. 전용 도구는 다음과 같습니다. 더 안전하게 이동하는 방법 참가 하시겠습니까?
  • 다른 사람이 jq을 (를) 사용하는 것을 보았지만 타사없이 이것을 구문 분석 할 수있는 방법이 없습니다. 도구?
  • 파일에서이 데이터를 가져 오나요? 둘 이상의 키 / 값 쌍이있을 수 있습니까? 큰 따옴표는 값의 일부로 어떻게 표시됩니까?
  • @kev : 기술적으로는 awk, sed , grep도 타사 도구입니다. json 데이터를 사용하는 경우 작업을위한 적절한 도구가 없을 이유가 전혀 없습니다.
  • 이 데이터는 내가 명령 한 결과입니다. 내 스크립트에서 실행되었습니다. 항상이 형식 (키 1 개 및 값 1 개)입니다.

답변

jq :

id="{"name":"john"}" key=$(jq -r keys[] <<<"$id") value=$(jq -r .[] <<<"$id") 

-r :이 옵션을 사용하면 필터가 결과가 문자열이면 따옴표가있는 JSON 문자열 형식이 아닌 표준 출력에 직접 기록됩니다.

keys : 다음과 같은 경우 내장 기능 키 객체가 주어지면 해당 키를 배열로 반환합니다.


json 사용 :

id="{"name":"john"}" key=$(json -ak <<<"$id") value=$(json -a "$key" <<<"$id") 

-a는 입력을 배열로 처리

-k는 키 값을 반환합니다.

댓글

  • 설명해 주셔서 감사합니다. 잘 작동합니다. ' '는
  • @kev : 문자열을 구문 분석하는 방법은 많지만 '는 불공평합니다. 이것을 json 데이터가 아닌 문자열이라고 부릅니다.
  • @kev JSON 데이터를 인코딩 할 수 있습니다. 이를 구문 분석하려면 잠재적으로 디코딩해야합니다. 또한 JSON은 키와 값 사이의 공백 (줄 바꿈 등)을 고려하지 않으므로이를 고려해야합니다. 이 작업은 jq의 기본 JSON 파서 작성자에 의해 이미 수행되었습니다.
  • Answer

    당신은 말 그대로 understand string parsing in bash를 요청 했으므로 문제에 대한 잘못된 해결책 . bash 자체를 사용하여 원하는 작업을 수행 할 수 있습니다. 정말 깨끗합니다. 특수 문자가없는 데이터. 여기서 특수 [A-Za-z0-9 ] :

    $name":"john"}" $ # remove everything through the first "{" $ echo $id "name":"john"} $ # remove everything starting with the last "}" $ echo $id "name":"john" $ name="${id%:*}" # take everything before the ":" $ name="${name//\"/}" # remove quotes $ echo $name name $ value="${id#*:}" # take everything after the ":" $ value="${value//\"/}" # remove quotes $ echo $value john 

    이 모든 내용은 bash 매뉴얼 의 “매개 변수 확장”에 설명되어 있습니다. 예를 들어 ${parameter#word}Remove matching prefix patternword의 시작 부분에서 텍스트를 제거합니다. div id = “5117616741”>

    . 마찬가지로 %는 접미사를 제거합니다. //는 문자열의 모든 항목을 그 뒤에 오는 모든 문자열로 대체합니다 (위의 ${foo//\"/} 예에서 따옴표 (이스케이프해야 함). \"로 표시됨)은 빈 문자열로 대체됩니다. 그러나 각각의 대체를 자체적으로 수행해야합니다. “하나의 명령으로 문자열의 시작 끝을 제거 할 수 없습니다.

    당신은 또한 당신이 알고있을 것입니다. }, {"와 같은 특수 문자를 이스케이프해야합니다. 올바른 방법을 기억하는 한, 이와 같은 코드를 매우 쉽게 작성 할 수 있지만 간단하지만 쓰기 전용 코드가되는 경향이 있습니다. 재사용을 위해 1 ~ 2 년 안에 코드를 작성하면 “#*\{}와 같은 것을보고 스스로 생각할 것입니다. WTF가 그게 의미하는 건가요? 그리고 그런 다음 맹목적으로 새 프로젝트에 복사하면 예상하지 못한 특수 문자가 발생하기 때문에 코드가 미묘하게 손상됩니다.

    위의 예는 이름-값 쌍에 중괄호, 이스케이프 된 따옴표, 콜론 또는 기타 문자와 같은 특수 문자가있는 경우 중단됩니다. 따라서 이것은 빠르고 더러운 스크래핑 또는 80 % 사용 사례에서는 잘 작동하지만 실제로는 프로덕션에서 사용하거나 항상 모든 입력에서 작동하는지 확인해야 할 때 사용해서는 안됩니다.

    어떤 일이 발생하는지 보여주는 echo 문이 없더라도이 코드는 수행 방법을 보여주는 다른 답변의 예제보다 이미 길다는 것을 알 수 있습니다. 정확히. 따라서 타사 도구를 사용하지 않음으로써 작성하는 데 더 많은 코드를 제공하게되므로 작성 및 디버그에 더 많은 시간이 소요되며 유연성이 떨어지고 예상치 못한 일이 발생하면 중단됩니다.

    댓글

    • 이것은 매우 유익했습니다. ' 사람들이 반대표를 던지는 이유를 이해하지 못함

    답변

    또는 도보 경로 기반 유닉스를 사용할 수 있습니다. 유틸리티 jtc :

    id="{"name":"john"}" bash $ key=$(jtc -w"[0]<>k" <<<"$id") bash $ echo $key "name" bash $ value=$(jtc -w"[0]" <<<"$id") bash $ echo $value "john" bash $ 

    PS> 공개 : 저는 jtc-shell cli 도구의 제작자입니다. JSON 작업용

    답글 남기기

    이메일 주소를 발행하지 않을 것입니다. 필수 항목은 *(으)로 표시합니다