이 문서의 큰따옴표 배열 확장이 여기서 작동하지 않는 이유는 무엇입니까?

이 문서의 큰따옴표 배열 확장이 여기서 작동하지 않는 이유는 무엇입니까?

두 개의 배열이 있습니다

$ arr1=( 1 2 2 3)
$ arr2=( 2 3 3 4)

큰따옴표 배열 확장의 모범 사례를 따를 때 이상한 출력이 생성되는 이유는 무엇입니까?

$ tsort << EOF
> "${arr1[@]}" "${arr2[@]}"
> EOF
"1
"2
2
3
3"
4"

그리고 모범 사례를 따르지 않으면 올바른 결과가 나올까요? 나는 무엇을 해야 합니까? 감사해요.

$ tsort << EOF
${arr1[@]} ${arr2[@]} 
EOF

1
2
3
4

여기 문서에서는 단어 분할이 여전히 수행되고 있다고 생각합니다.

$ wc -l << EOF
a    
b  
1
EOF
3

답변1

~에서배쉬 매뉴얼:

[...] 이 문서의 모든 행은 매개변수 확장, 명령 대체 및 산술 확장을 거치며 문자 순서  \newline 는 무시되며 ' ', ' ' 및 ' ' 문자는 \' ' 를 사용하여 인용되어야 합니다 .\$`

따옴표 제거, 필드 분할 또는 파일 이름 확장에 대해서는 아무 말도 하지 않으므로 구분된 문서의 따옴표는 문자 그대로 받아들여 일반적인 기능을 수행하지 않습니다.

답변2

또 다른 대답기본적으로 "왜냐면수동말하자면"이라고 할 수 있지만 내 생각엔 그런 사람들도 있는 것 같아이유이 행동 뒤에.

이러한 유형의 리디렉션은 행에 다음 항목만 포함될 때까지 현재 소스에서 입력을 읽도록 쉘에 지시합니다.단어(후행 공백 없음) 표시됩니다. 해당 지점까지 읽은 모든 줄은 다음과 같이 사용됩니다.표준 입력[...] 주문하다.

[…]

만약 어떤 부분이라도단어따옴표가 붙은 경우 구분 기호는 따옴표를 제거한 결과입니다.단어, 여기 문서의 줄은 확장되지 않습니다. 만약에단어따옴표 없이 여기에 있는 문서의 모든 줄에는 매개변수 확장, 명령 대체 및 산술 확장 [...]이 적용되었습니다.

(강조).

명령줄에서 인용을 고려해야 하는 주된 이유는 다음과 같습니다.

  1. 줄을 분할하고 매개변수 목록을 생성하는 방법을 쉘에 알려줍니다(두 개의 매개변수 a b대 하나의 매개변수 "a b").
  2. ''확장을 수행해야 하는지( 상대 ""또는 따옴표 없음) 여부를 쉘에 알려줍니다 .

표준 입력을 생성할 때 첫 번째 이유는 적용되지 않습니다.개울그리고 매개변수 개수에 대한 개념이 없습니다. 두 번째 이유가 적용될 수 있지만 디자인 선택은 인용 여부에 의해서만 확장을 제어합니다.단어( "EOF"vs. EOF)는 무효로 만듭니다.

나는 무엇을 해야 합니까?

여기에서 스트림을 생성한다는 점을 기억해야 합니다. 따옴표를 사용하는 이유습관그 안에 나타나는 것은 더 이상 유효하지 않습니다. 사실, 전제는 당신이 사용하는 모든 참고자료가~해야 한다스트림에 나타납니다.

예상한 것보다 크면 이스케이프 처리되지 않은 따옴표가 사라집니다.차이 없음. 나는 여기에 있는 문서가 참조가 보존되어야 함을 지원 \"하고 나타낼 것이라고 생각합니다. \'그러나 이것은 실제로 사용해야 할 유일한 인용문이 될 것입니다. 현재 상황은 일을 더 쉽게 만듭니다.

답변3

다음으로 대체하면 실제로 tsort어떤 일 이 발생하는지 살펴보겠습니다 cat.

$ arr1=( 1 2 2 3 )
$ arr2=( 2 3 3 4 )
$ cat <<END
> "${arr1[@]}" "${arr2[@]}"
> END
"1 2 2 3" "2 3 3 4"

보시다시피 여기서 문서는 확장된 배열 값을 포함하는 텍스트 문자열에 지나지 않습니다. 큰 따옴표는 문서 자체의 큰 따옴표에서 나옵니다(셸은 해당 ${...}비트에만 관심을 갖고 따옴표 문자는 건드리지 않습니다).

큰따옴표를 제거할 때의 출력은 동일하지만 큰따옴표가 없습니다.

1 2 2 3 2 3 3 4

tsort이는 다음 과 같이 해석될 것이다 .

1 2   <-- first two numbers from arr1
2 3   <-- last two numbers from arr1
2 3   <-- first two numbers from arr2
3 4   <-- last two numbers from arr2

불행하게도 당신이 이 특별한 예를 선택한 이유는 다음과 같기 때문입니다.

1 2   <-- first number from arr1 and arr2
2 3   <-- second number from arr1 and arr2
2 3   <-- etc.
3 4

즉, 각 배열의 항목은 두 개의 열(각 배열당 하나의 열)로 나뉩니다.

두 번째 목록을 (올바르게) 생성하려면 실제로 여기 문서를 사용할 수 없습니다. 대신 쉘 루프를 사용할 수 있습니다.

for (( i=0; i<${#arr1[@]}; ++i)); do
    printf '%d %d\n' "${arr1[i]}" "${arr2[i]}"
done | tsort

관련 정보