
다음 샘플 스크립트가 있는데 배열의 길이가 정확히 무엇인지 알고 싶습니다. 바이트, 문자 또는 다른 것입니까?
#!/bin/bash
# Arrays
# @ vs. *
ape=( "Apple Banana" "Emacs Window" "Panda Bamboo Nature" )
cape=( 'Ping Pong' 'King Kong' 'King Fisher Club' 'Blurb' )
jade=( ally belly cally delly )
echo Expansion with \*
echo ${ape[*]}
echo ${cape[*]}
echo -e "${jade[*]}\n"
echo Expansion with \@
echo ${ape[@]}
echo ${cape[*]}
echo -e "${jade[@]}\n"
echo Elements with \*
echo ${#ape[*]}
echo ${#cape[*]}
echo ${#jade[*]}
echo Elements with \@
echo ${#ape[@]}
echo ${#cape[@]}
echo ${#jade[*]}
echo -e "\nLength"
echo ${#ape}
echo ${#cape}
echo ${#jade}
내가 아는 매뉴얼 페이지에서 배열 확장은 단어가 큰따옴표로 묶인 경우와 다르지만 *
아무런 차이가 없습니다. @
두 경우 모두 동일한 결과를 얻는 이유는 무엇입니까?
출력은 다음과 같습니다.
Expansion with *
Apple Banana Emacs Window Panda Bamboo Nature
Ping Pong King Kong King Fisher Club Blurb
ally belly cally delly
Expansion with @
Apple Banana Emacs Window Panda Bamboo Nature
Ping Pong King Kong King Fisher Club Blurb
ally belly cally delly
Elements with *
3
4
4
Elements with @
3
4
4
Length
12
9
4
답변1
*
배열을 단일 문자열로 확장하고 @
개별적으로 인용된 문자열로 확장하는 모습을 놓쳤습니다.
printf 'string "%s"\n' "${cape[*]}"
이것은 생산할 것입니다
string "Ping Pong King Kong King Fisher Club Blurb"
그리고
printf 'string "%s"\n' "${cape[@]}"
이것은 생산할 것입니다
string "Ping Pong"
string "King Kong"
string "King Fisher Club"
string "Blurb"
echo
단순히 인수를 연결하여 인쇄하는 대신 printf
형식 문자열을 인수로 채우고 더 많은 인수가 제공되면 동일한 형식을 반복한다는 점을 기억하십시오 .
반품,
for s in "${cape[*]}"; do
echo "$s"
done
단일 출력 라인을 생성합니다(단일 문자열만 반복함).
for s in "${cape[@]}"; do
echo "$s"
done
각 배열 요소에 대해 하나씩 생성합니다.
${array[*]}
${array[@]}
어떤 이유로든 단어 분리 및 파일 이름 글로빙을 명시적으로 호출하려는 경우가 아니면 항상 및 확장 주위에 큰따옴표를 사용하는 것이 좋습니다 . *
or 의 사용은 @
배열 요소가 모두 하나의 문자열로 필요한지 아니면 개별적으로 인용되는지에 따라 달라집니다.
내 경험상 거의 사용되지 않습니다 [*]
.
배열의 길이를 얻을 때 *
어느 것을 사용하는지는 중요하지 않습니다. @
그러나 둘 다 사용하지 않으면 배열의 첫 번째 요소의 문자 길이를 얻게 됩니다.
답변2
변수 할당에 사용하는 다른 인용을 기반으로 "단어가 큰 따옴표로 묶인 경우"라는 문구를 "배열 요소가 큰 따옴표로 묶인 경우"라는 의미로 잘못 해석하고 있다고 생각합니다. "변수의 단어가 큰따옴표로 묶여 있는지 여부를 확장한다는 의미입니다."
같은 줄에서 발생하는 변수 확장을 사용할 수도 있습니다 . 다음 echo
과 같이 보다 구성 가능한 항목을 사용하면 더 깔끔한 결과를 얻을 수 있습니다.printf
좋은 일을 했어 Nanda가 해냈어) 또는 다음과 같습니다.
$ printf -- '->%s<-\n' "${ape[@]}"
->Apple Banana<-
->Emacs Window<-
->Panda Bamboo Nature<-
printf가 수행하는 중간 값을 볼 수 있으면 다음과 같이 표시됩니다.
printf -- '->%s<-\n' "Apple Banana" "Emacs Window" "Panda Bamboo Nature"
인용되지 않은 버전과 달리:
$ printf -- '->%s<-\n' ${ape[@]}
->Apple<-
->Banana<-
->Emacs<-
->Window<-
->Panda<-
->Bamboo<-
->Nature<-
...여기서 중간 값은 다음과 같습니다.
printf -- '->%s<-\n' Apple Banana Emacs Window Panda Bamboo Nature
...이것은 요소가 확장된 대상을 정확하게 보여줍니다. 첫 번째 경우에는 변수가 참조되므로 더 이상 토큰화가 발생하지 않으며 세 가지 요소를 얻게 됩니다. 두 번째 경우에는 세 가지 요소 각각도 분사를 거치므로 printf
다음을 참조하세요 .일곱인쇄할 요소입니다.
배열의 "길이"는 일반적으로 구문을 사용하여 생성된 요소 수입니다 ${#ape[@]}
. bash를 사용하여 ${#ape}
첫 번째 요소의 길이를 물어보세요.
아래 첨자가 없는 배열 변수를 참조하는 것은 아래 첨자 0이 있는 배열 변수를 참조하는 것과 같습니다.
이것이 바로 서로 다른 값을 얻는 이유입니다.