コマンドラインから複数の文字列を読み、トイレのすべての文字列を読みたいです。ループでさらに処理(印刷など)する方法です。申し訳ありません。初心者です。初心者の質問についてご了承ください。
#!/usr/bin/bash
echo "Enter the number of names of students"
read classcount
for ((i=1;i<=classcount;i++)); do
read names[${i}]
done
for ((i=1;i<=classcount;i++)); do
echo $names[${i}]
done
ベストアンサー1
通常、スクリプトまたはコマンドラインで使用されるユーティリティでのユーザー対話を避けるのが最善です。自動化を妨げる可能性があるからです。
たとえば、を呼び出すと、削除したいファイルの数を尋ねられ、各ファイルに対して個別にメッセージが表示されることを期待しないrm file1 file2 'file 3'
でください。rm
繰り返しますが、ここに記載することをお勧めします学生コマンドラインパラメータから:
#! /usr/bin/bash -
classcount=$#
names=("$@")
if (( classcount > 0 )); then
echo "Student${name[1]+s}:"
printf ' - %s\n' "${name[@]}"
fi
次のように呼び出されます。
that-script 'John Doe' 'Alice Smith' ...
または、テキストファイルから1行に1つずつ学生のリストを取得します(GNUと仮定xargs
)。
xargs -d '\n' -a student.list that-script
標準入力から各行を読み取ることもできますが、最初に数を求めるのではなく、対話なしで対話し、入力が終わるまでリストを読むことをお勧めします。
#! /usr/bin/bash -
readarray -t names
classcount="${#names[@]}"
if (( classcount > 0 )); then
echo "Student${name[1]+s}:"
printf ' - %s\n' "${name[@]}"
fi
stdinが端末の場合、ユーザーは入力の終わりを示すために使用されますCtrl+D。
ファイルからリストを取得するには:
that-script < student.list
read
stdinから1行を読み取るために使用できますが、構文はIFS= read -r lvalue
isではありませんread lvalue
。
また、これは[...]
ワイルドカードなので、リストのコンテキストに表示されるすべてのパラメータ拡張のように引用する必要があります。
また、配列インデックス(Bourne配列を除く"$@"
)は、bash
inと同様にksh
(しかし他のほとんどのシェルとは異なり)1ではなく0から始まります。
したがって、あなたの方法の構文は次のとおりです。
#! /usr/bin/bash -
PROGNAME=$0
die() {
(( $# == 0 )) || printf >&2 '%s: ERROR: %s\n' "$PROGNAME" "$1"
exit 1
}
IFS= read -rp "Enter the number of names of students: " classcount || die
# validate to avoid command injection vulnerability
shopt -s extglob # only needed in older versions of bash
[[ $classcount = @(0|[123456789]*([0123456789])) ]] ||
die "Not a valid decimal integer number: $classcount"
for (( i = 1; i <= classcount; i++ )); do
IFS= read -rp "Student $i: " 'names[i-1]' ||
die "$(( classcount - i + 1 )) students missing"
done
for (( i=1; i <= classcount; i++)); do
printf 'Student %s: %s\n' "$i" "${names[i-1]}"
done
$name[$i]
(t)csh(1970年代後半に配列が最初に導入されたシェル)で動作しますが、コピーの配列設計である$name[$i]:q
zshでスペースやワイルドカードが特に処理されないようにする必要があります。bash
ksh
この点に関して、ksh は Bourne シェルと逆互換性を持っているので、Bourne シェルと同様に、パターンと一致するecho $name[$i]
ファイルのリストが出力<contents-of-$name>[<contents-of-$i>]
($name
および分割)されます。$i
ksh / bashには構文が必要です${name[i]}
(${name[$i]}
またはそれも機能します)、すべてのパラメータ拡張と同様に、分割+globを避けるために${name[${i}]}
引用符で囲む必要があります。"${name[i]}"
いずれにせよ、echo
任意のデータの出力には使用できません。。