두 개의 배열이 있습니다
$ 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
또 다른 대답기본적으로 "왜냐면수동말하자면"이라고 할 수 있지만 내 생각엔 그런 사람들도 있는 것 같아이유이 행동 뒤에.
이러한 유형의 리디렉션은 행에 다음 항목만 포함될 때까지 현재 소스에서 입력을 읽도록 쉘에 지시합니다.단어(후행 공백 없음) 표시됩니다. 해당 지점까지 읽은 모든 줄은 다음과 같이 사용됩니다.표준 입력[...] 주문하다.
[…]
만약 어떤 부분이라도단어따옴표가 붙은 경우 구분 기호는 따옴표를 제거한 결과입니다.단어, 여기 문서의 줄은 확장되지 않습니다. 만약에단어따옴표 없이 여기에 있는 문서의 모든 줄에는 매개변수 확장, 명령 대체 및 산술 확장 [...]이 적용되었습니다.
(강조).
명령줄에서 인용을 고려해야 하는 주된 이유는 다음과 같습니다.
- 줄을 분할하고 매개변수 목록을 생성하는 방법을 쉘에 알려줍니다(두 개의 매개변수
a b
대 하나의 매개변수"a b"
). ''
확장을 수행해야 하는지( 상대""
또는 따옴표 없음) 여부를 쉘에 알려줍니다 .
표준 입력을 생성할 때 첫 번째 이유는 적용되지 않습니다.개울그리고 매개변수 개수에 대한 개념이 없습니다. 두 번째 이유가 적용될 수 있지만 디자인 선택은 인용 여부에 의해서만 확장을 제어합니다.단어( "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