나는 물건을 다운로드하는 스크립트를 작성 중입니다.
스크립트에서 반복적으로 다운로드될 이름과 URL(따라서 스크립트)을 연결해야 합니다.
name1,url1
name2,url2
name3,url3
command $NAME $URL
그래서 나는 이름 목록과 해당 URL 목록을 반복하기 위해 모든 루프를 원합니다. 이를 달성하는 가장 좋은 방법은 무엇입니까? 현재는 이 목록을 외부 파일이나 다른 곳에 저장하는 데 관심이 없습니다. 대본에는 내가 원하는 것의 예가 있습니다.
답변1
bash
이와 관련하여 매우 제한적입니다. 다른 쉘을 사용해 볼 수도 있습니다.
사용하십시오 ( 에서 변수를 인용하지 않았으므로 zsh
이미 구문을 사용하고 있습니다 ).zsh
command $NAME $URL
for name url (
name1 url1
name2 url2
name3 url3
) command $name $url
bash
POSIX 셸 또는 기타 POSIX 셸을 사용하면 다음을 수행할 수 있습니다.
while IFS=, read <&3 -r name url; do
{
command "$name" "$url"
} 3<&-
done 3<< "EOF"
name1,url1
name2,url2
name3,url3
EOF
이는 값에 쉼표나 개행 문자를 포함할 수 없음을 의미합니다.
최신 버전은 bash
ksh93과 유사한 구문을 사용하여 연관 배열도 지원합니다 zsh
. 따라서 이름이 고유한 경우 다음을 수행할 수 있습니다.
typeset -A pairs
pairs=(
[name1]=url1
[name2]=url2
[name3]=url3
)
for name in "${!pairs[@]}"; do
url=${pairs[$name]}
command "$name" "$url"
done
이는 또한 적용됩니다 ksh93
. 인용 규칙은 둘 사이에 약간 다릅니다. 에서는 zsh
연관 배열 정의 구문이 더 간단하며 일반적인 인용 규칙이 적용됩니다.
pairs=(name1 url1 name2 url2 name3 url3)
다음과 같이 몇 줄로 입력할 수 있습니다.
pairs=(
name1 url1
name2 url2
name3 url3
)
2021년 편집: 이제 ksh93 구문이 zsh
지원되고 zsh 구문 도 지원됩니다 .hash=([key]=value)
bash
hash=(key value)
순서는 유지되지 않으며 bash
연관 배열은 널 키를 지원하지 않습니다.
ksh93
다차원 배열이 지원되므로 다음과 같이 할 수 있습니다.
pairs=((name1 url1) (name2 url2) (name3 url3))
for ((i = 0; i < ${#pairs[@]}; i++)); do
name=${pairs[i][o]} url=${pairs[i][1]}
command "$name" "$url"
done
execve()
또는 NUL, 엄밀히 말하면 NUL은 시스템 호출을 통해 실행되는 명령 에 전달될 수 없지만이름섹션에는 쉼표를 포함할 수 없지만URL부분은 2개 이상이면 괜찮고, 1개만 있어도 끝이 아닙니다. 그 방식은 $IFS
하나를 제외하고는 쉘에서 분할하는 것으로 해석되기 때문입니다 zsh
.
답변2
여기 문서를 생성하여 임시 파일에 쓴 후 처리할 수 있습니다. 임시 파일은 자동으로 삭제되므로 수동으로 정리할 필요가 없습니다.
#!/bin/bash
mylist=/var/tmp/$$
trap 'rm -f ${mylist}' EXIT
cat << _EOF_ > ${mylist}
name1 url1
name2 url2
name3,url3
_EOF_
while read name url
do
printf "%s %s\n" ${name} ${url}
done < ${mylist}
답변3
처음에는 연관 배열만큼 복잡한 것을 생각했습니다.
그런 다음 URL만큼 이름이 많다는 점을 고려하면 다음과 같이 간단하게 수행할 수 있다는 것을 깨달았습니다.
root@debian:a=( "name1,url1" "name2,url2" "name3,url3" );while IFS="," \
read -r name url;do echo "command $name $url";done<<<$(printf '%s\n' "${a[@]}")
command name1 url1
command name2 url2
command name3 url3
당신이 해야 할 일은 이름과 URL을 동일한 배열(내 테스트에서는 a)에 쉼표로 구분하여 저장하는 것뿐입니다.
답변4
아마도 간단한 bash 스크립트가 도움이 될 것입니다.
pairs=( "name1,url1" "name2,url2" "name3,url3" )
for pair in "${pairs[@]}"; do
IFS=, read name url <<<"${pair}"
printf "%s %s\n" "${name}" "${url}"
command "${name}" "${url}"
done