나는 Unix 쉘 스크립팅을 처음 접했고 내 코드는 다음과 같습니다.
i=0
for var in 'a' 'b' 'c' 'd' 'e'
do
content[i]=var
((i=`expr i+1`))
done
a=10
b=50
c=40
d=90
e=100
Now I wanted to print the local variables contents using array into the function
print_array
{
echo "${content[0]}"
echo "${content[1]}"
echo "${content[2]}"
echo "${content[3]}"
echo "${content[4]}"
}
내가 원하는 배열 내용은 {a,b,c,d,e}이고 a,b,c,d,e라는 로컬 변수가 있고 일부 할당된 값이 있습니다. The를 사용하여 이러한 로컬을 인쇄하고 싶습니다. 변수 배열의 이름, 배열 요소와 지역 변수 요소의 이름이 동일하므로 $와 array_names를 다양하게 조합하여 참조 호출을 시도했지만 작동하지 않았습니다.
답변1
그래서 먼저 간접인쇄 기능을 정의하는데...
_print() while [ "$#" -ne 0 ]
do printf '$%s = %d\n' \
"$1" "$(($1))"
shift
done
다음으로 배열을 설정하고 증분하겠습니다.
arr=( a b c d e ); i=0
for var in "${arr[@]}"
do : "$(($var=(i+=10)))"
done
따라서 이제 값은 $a
10과 $b
20 등이 됩니다. 드디어 인쇄만 남았네요...
_print "${arr[@]}"
...표준 출력으로 인쇄...
$a = 10
$b = 20
$c = 30
$d = 40
$e = 50
$((
이 모든 것은 쉘이 수학 확장을 처리하는 방식 때문에 작동합니다 ))
. 기본적으로는 eval
s입니다. 산술 확장에서는 쉘첫 번째확장하다어느수학을 시도하기 전에 다른 효율적인 쉘 확장을 수행하십시오. 실제 수학을 마지막 작업으로 만드십시오.
이는 다음을 의미합니다.
i=a a=10; echo "$(($i))"
인쇄된 결과는 10
쉘이 $i
get의 값을 확장한 a
다음 이를 평가하기 때문입니다.저것결과는 정수로 참조됩니다.
위 코드는 모든 POSIX 호환 셸에서 실행될 수 있습니다.
그러니까 나도 아마 그랬을 거라는 뜻이겠지...
i=10
for var in a b c d e
do arr[($var=i*${#arr[@]}+i)/i]=$var
done
$var
[
...이름이 지정된 쉘 배열(이를 지원하는 쉘에서)의 인덱스 ]
대괄호는 수학 표현식의 확장 대괄호와 동일하기 때문에 배열 할당, 인덱스 평가 및 정수 할당을 동시에 처리합니다 $((
.))
명령에 포함된 위 코드를 실행하면 ksh -xc
다음 디버그 출력이 표준 오류로 인쇄됩니다.
+ arr[1]=a
+ arr[2]=b
+ arr[3]=c
+ arr[4]=d
+ arr[5]=e
거기에서 나는 할 수 있습니다 :
echo "$((${arr[1]}))"
echo "$((a))"
...인쇄...
10
10
...이름이 지정된 배열을 지원하는 셸에서 동일하게 평가하기 때문입니다. 그러나 아니...
echo 'arr=(a b c d e)' | bash -x
+ arr=(a b c d e) #bash traces the successful command to stderr
echo 'arr=(a b c d e)' | sh -x
sh: 1: Syntax error: "(" unexpected #sh traces something else
그래서 _print()
함수에서 나는 shift
위치 인수를 넣었습니다.(진정한 휴대용 쉘 "$@"
배열을 나타냄)어떤 것이 있지만 printf
...
$
먼저 달러 기호 가 있습니다 .- 그런 다음 첫 번째 위치 매개변수
%s
에 문자열 값을 저장합니다 .$1
=
그 다음에는 등호가 있습니다 .- 마지막으로 값을 저장합니다.값은 다음 위치에 저장됩니다.내
$(($1))
첫 번째 위치 매개변수입니다.
함수 shift
의 인수가 사라지면 위치 인수 $#
개수가 0이 되고 함수가 반환될 때까지 첫 번째 위치 인수가 다음 위치 인수로 계속 대체됩니다.
함수를 실행하기 전에 배열과 간접 변수를 초기화하면 다음과 같이 작동합니다.
for var in "${arr[@]}"
[@]
쉘은 다음으로 확장됩니다 .목록매개변수와[*]
이 목록의 단일 연결입니다. 확장자가 참조되지 않는 경우가능한[*]
또한 완료 시 값이 있는지 여부와 현재 파일 이름 확장이 어떻게 구성되어 있는지 에 따라 목록으로 확장되지만 이렇게 하면 원하는 방식으로 작동하지 않을 수 있습니다.$IFS
set -f
: "$(($var=(i+=10)))"
- 의 각 값은 차례로
${arr[@]}
해당 값에 할당됩니다. 그런 다음 확장$var
$(($var=(i+=10)))
첫 번째$var
like 의 값에 대해$((a=(i+=10)))
마지막에 모든 계산을 수행합니다. 먼저$i
10씩 증가한 다음 값을 에 할당$i
합니다$a
.
- 의 각 값은 차례로
답변2
노력하다
#i=0
for var in 'a' 'b' 'c' 'd' 'e'
do
content[${#content[*]}]=$var # or content[i++]=$var
done
# or just content=( 'a' 'b' 'c' 'd' 'e' )
a=10
b=50
c=40
d=90
e=100
for i in "${#content[@]}"
do
echo ${!i}
done
답변3
내가 올바르게 이해했다면 변수 액세스에 대한 간접 참조가 필요합니다 bash
. 예를 들어 다음 코드를 사용하면 됩니다.
content=( a b c d e )
a=10
b=50
c=40
d=90
e=100
echo "${!content[0]}"
echo "${!content[1]}"
echo "${!content[2]}"
echo "${!content[3]}"
echo "${!content[4]}"
당신은 다음과 같은 것을 얻을 것입니다 :
10
50
40
90
100
여기서 핵심은 bash
구체적인 변수 확장 접근 방식 이다 "${! ... }"
.