heredoc의 JSON 컨텐츠를 구문 분석 할 수없는 이유는 무엇입니까?


11

JSON 조각이 있습니다.

다음은 작동하지 않습니다.

VALUE=<<PERSON
{
  "type": "account",
  "customer_id": "1234",
  "customer_email": "jim@gmail.com"  
}
PERSON
echo -n "$VALUE" | python -m json.tool

결과는 다음과 같습니다.

JSON 객체를 디코딩 할 수 없습니다

와 같은 일을하는 것 jq, 즉

echo -n "$VALUE" | jq '.'

출력이 없습니다.

다음과 같은 동작이 있습니다.

VALUE=<<PERSON
'{
  "type": "account",
  "customer_id": "1234",
  "customer_email": "jim@gmail.com"  
}'
PERSON
echo -n "$VALUE" | python -m json.tool

응답:

JSON 객체를 디코딩 할 수 없습니다

그러나 다음과 같이 작동합니다.

VALUE='{
  "type": "account",
  "customer_id": "1234",
  "customer_email": "jim@gmail.com"
}'
echo -n "$VALUE" | jq '.'
echo -n "$VALUE" | python -m json.tool

5
나는 떠들썩한 파티가 무엇을하고 있는지 모르겠지만, 후행 쉼표의 이메일 문자열 뒤에있어 처음이 아니라 처음 몇 불법 JSON 할 것이다, 세 번째에
닉 T

@ NickT 당신은 내가 정확히 문제라고 생각하는 대답을해야합니다.
rrauenza

그것이 (발바닥) 답이라면 아마도 "복제 할 수 없습니다 (오타)"로 닫혀 있어야합니다. 그러나 Kusa와 terdon의 대답에 따르면 할당 + 리디렉션이 완전히 손상되어 빈 문자열이 표시되므로 두 가지 문제가 있으며 두 가지 문제는 모두 동일한 "No JSON ..."오류를 발생시키는 것입니다. 중간에 가정을 확인하여 문제를 양분하는 것이 가장 좋습니다. 간단한 정보가 echo $VALUE없으면 간단한 ... | jq정보를 얻을 수 있습니다.
Nick T

@NickT : 복사 / 붙여 넣기 문제였습니다. 혼란을 드려 죄송합니다
Jim

답변:


19
VALUE=<<PERSON
some data
PERSON

echo "$VALUE"

출력이 없습니다.

here-document는 리디렉션 이므로 변수로 리디렉션 할 수 없습니다.

명령 행을 구문 분석 할 때 경로 재 지정은 변수 지정과 별도의 단계에서 처리됩니다. 따라서 귀하의 명령은 (공백에 유의하십시오)

VALUE= <<PERSON
some data
PERSON

즉, 빈 문자열을 변수에 할당 한 다음 here-string의 표준 입력을 명령으로 리디렉션합니다 (그러나 명령이 없으므로 아무 일도 일어나지 않습니다).

참고

<<PERSON
some data
PERSON

있는 그대로 유효합니다

<somefile

표준 입력 스트림이 데이터를 포함하도록 설정할 수있는 명령이 없으므로 그냥 손실됩니다.

그래도 작동합니다.

VALUE=$(cat <<PERSON
some data
PERSON
)

여기에서 here-document를받는 명령 cat은 표준 출력으로 복사됩니다. 그런 다음 명령 대체를 통해 변수에 지정됩니다.

귀하의 경우 대신 사용할 수 있습니다

python -m json.tool <<END_JSON
JSON data here
END_JSON

변수에 데이터를 저장하는 추가 단계를 수행하지 않아도됩니다.


2
PERSON="줄 바꿈과 여러 줄 데이터 가 이어질 수도 "있고 마지막에 다른 줄 이 이어질 수도 있습니다 .
R .. GitHub 중지 지원 얼음

1
@R .. 예, 그러나 여기 문서를 사용하면 쉘의 인용 규칙을 무시할 수 있습니다. 따라서 여러 줄 데이터에 대해 인용 문자열 대신 여기 문서를 사용하는 것이 특히 안전합니다.
Kusalananda

2
@R .. 우리가 이야기하는 JSON이기 때문에 각 속성 이름의 큰 따옴표를 이스케이프 처리하지 않으려면 작은 따옴표를 사용하는 것이 좋습니다. PERSON='. OP가 나중에 변수를 보간하지 않는 한 그렇지 않습니다.
JoL

구분 기호 단어를 인용하거나 이스케이프 처리하더라도 여기 문서에서 (백 슬래시) (개행)가 사라지는 것 같습니다. 바람직 할 수도 있지만 비활성화 할 수있는 방법이 있습니까?
Scott

@Scott 이전에이 사이트에서 그 질문을받지 않았다면, 그 자체로는 훌륭한 질문이 될 것입니다.
Kusalananda

11

변수가 heredoc에 의해 설정되지 않기 때문에 :

$ VALUE=<<PERSON  
> {    
>   "type": "account",  
>   "customer_id": "1234",  
>   "customer_email": "jim@gmail.com",  
> }  
> PERSON
$ echo "$VALUE" 

$

heredoc을 사용하여 변수에 값을 할당하려면 다음과 같은 것이 필요합니다.

$ read -d '' -r VALUE <<PERSON  
{    
  "type": "account",  
  "customer_id": "1234",  
  "customer_email": "jim@gmail.com",  
}   
PERSON

1
JSON 데이터를 작은 따옴표로 묶는 이유는 무엇입니까? OP가 입력 문자열의 일부가되기를 원하는 것처럼 보이지 않습니다. 그 외에도, 노숙자 고양이 수를 줄이려면 +1입니다. Kusalananda의 답변과 마찬가지로 입력 줄의 s 및 줄 끝의 백 슬래시 << \PERSON로부터 보호 하는 것이 좋습니다 $.
Scott

@Scott um, 방금 OP의 텍스트를 맹목적으로 복사했기 때문입니다. 감사합니다
terdon

3
이것이 정답입니다. $(cat <<EOF ... EOF)서브 쉘을 실행 한 다음 heredoc을 cat로 보내서 STDOUT으로 보낸 다음 해당 서브 쉘의 결과를 변수에 할당하는 이상한 구성이 있습니까? 사람들이 자신의 사고 과정에 대해 말하는 것을 생각하기를 바랍니다 . 를 통해 heredoc을 변수에 할당하는 read것은 제정신입니다.
Rich

나는 $(cat << EOF… (데이터)… EOF )이상 하다고 말하지 않을 것입니다 . 어색하고 복잡하지만 read -d … << EOF 특히 그렇습니다 read -d '' << EOF . terdon의 답변은 내장 프로그램 만 사용하고 프로그램은 사용하지 않기 때문에 감사합니다. 그러나, 더 중요한 것은, $(cat << EOF(데이터) ... EOF )어떤 라인으로 끝나는 경우 실패 \(백 슬래시) - 아래의 설명을 참조 Kusalananda의 답변을 .
Scott

5

JSON과 함께 사용할 here-doc을 정의한 방식이 잘못 되었기 때문입니다. 당신은 그것을 사용해야합니다

VALUE=$(cat <<EOF
{  
  "type": "account",  
  "customer_id": "1234",  
  "customer_email": "jim@gmail.com",  
}
EOF
)

그리고 printf "$VALUE"예상대로 JSON을 덤프해야합니다.


3

Heredocs와 변수는 잘 혼합되지 않거나 적어도 이런 식으로 혼합되지 않습니다. 당신은 할 수 ...

heredoc을 응용 프로그램의 표준 입력으로 전달

python -m json.tool <<PERSON  
{
  "type": "account",
  "customer_id": "1234",
  "customer_email": "jim@gmail.com",
}
PERSON

또는…

쉘 변수에 여러 줄 텍스트 저장

VALUE='{
  "type": "account",
  "customer_id": "1234",
  "customer_email": "jim@gmail.com",
}'

내부 따옴표를 이스케이프 처리하지 않으려면 작은 따옴표를 사용했습니다. 물론 매개 변수를 확장 해야하는 경우 큰 따옴표를 사용할 수도 있습니다.

VALUE="{
  \"type\": \"account\",
  \"customer_id\": ${ID},
  \"customer_email\": \"${EMAIL}\",
}"

그런 다음 나중에 변수 값을 사용할 수 있습니다.

echo -n "$VALUE" | python -m json.tool
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.