POSIX 쉘 스크립트에서 의사 배열을 사용하는 방법은 무엇입니까?
Bash 스크립트에서 10개의 정수 배열을 다음으로 바꾸고 싶습니다.무엇POSIX 쉘 스크립트와 유사합니다.
나는 우연히 만날 수 있었다Rich의 sh(POSIX 쉘) 트릭, 단면에배열 사용.
내가 시도한 것:
save_pseudo_array()
{
for i do
printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/"
done
echo " "
}
coords=$(save_pseudo_array "$@")
set -- 1895 955 1104 691 1131 660 1145 570 1199 381
eval "set -- $coords"
이해가 안 돼요. 그게 문제인데, 누군가 설명해 주시면 정말 감사하겠습니다.
답변1
기본 아이디어는 set
배열에서 인덱스 값으로 작업하는 경험을 재현하는 것입니다. 따라서 배열로 작업하려면 set
다음과 같은 값을 사용하세요.
set -- 1895 955 1104 691 1131 660 1145 570 1199 381
$1
그런 다음 $2
등을 사용하여 for
주어진 값을 처리 할 수 있습니다 .
여러 배열이 필요한 경우에는 이 모든 것이 별로 유용하지 않습니다. 이것이 save
바로 eval
트릭이 들어오는 곳입니다.리치 save
기능1 현재 위치 인수를 처리하고 적절한 참조가 포함된 문자열을 출력합니다. 그런 다음 eval
저장된 값을 복원하는 데 사용할 수 있습니다. 그럼 넌 도망쳐
coords=$(save "$@")
현재 작업 중인 배열을 저장한 coords
다음 새 배열을 만들어 사용하고, 다시 사용해야 할 경우 다음을 수행할 coords
수 eval
있습니다.
eval "set -- $coords"
coords
이 예를 이해하려면 두 개의 배열, 즉 에 저장하려는 이전에 설정된 값이 있는 배열과 1895, 955 등을 포함하는 배열 로 작업하고 있다는 점을 고려해야 합니다 . 코드 조각 자체는 그다지 중요하지 않습니다. 그 자체로는 set
및 행 eval
사이에서 일부 처리를 수행 해야 합니다 . 나중에 1895, 955 어레이를 반환해야 하는 경우 복원하기 전에 어레이를 저장하십시오 coords
.
newarray=$(save "$@")
eval "set -- $coords"
이렇게 하면 $newarray
나중에 복원할 수 있습니다.
1은 다음과 같이 정의됩니다.
save () {
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " "
}
답변2
아이디어는 임의의 문자열 목록을 나중에 목록이나 임의의 문자열을 재구성하는 데 사용할 수 있는 형식의 스칼라 변수로 인코딩하는 것입니다.
$ save_pseudo_array x "y z" $'x\ny' "a'b"
'x' \
'y z' \
'x
y' \
'a'\''b' \
$
set --
앞에 지속하면 x
문자열 목록을 재구성하고 배열 y z
에 저장하는 셸 코드를 생성하므로 이를 사용하기만 하면 됩니다.$@
eval
sed
각 문자열을 올바르게 인용하는 일을 담당합니다 (첫 번째 줄의 시작 부분, 마지막 줄의 끝 부분에 모든 을 '
추가하고 교체 ).'
'\''
그러나 이는 각 인수에 대해 하나의 printf
명령을 실행하는 것을 의미하므로 sed
다소 비효율적입니다. 이는 awk를 한 번만 호출하여 보다 직접적인 방법으로 수행할 수 있습니다.
save_pseudo_array() {
LC_ALL=C awk -v q=\' '
BEGIN{
for (i=1; i<ARGC; i++) {
gsub(q, q "\\" q q, ARGV[i])
printf "%s ", q ARGV[i] q
}
print ""
}' "$@"
}