私はものをダウンロードするスクリプトを書いています。
スクリプトから繰り返しダウンロードされる名前と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
。引用規則は2つの間で若干異なります。では、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
1つを除いてはシェルで分割するものと解釈されるからです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