
ディレクトリ内に複数のファイルがあり、ファイル名全体を記述するのではなく、インデックスに基づいてどのファイルを選択するかをユーザーが選択できるように、すべてのファイルをその横のインデックスとともにリストする bash スクリプトを作成しています。
例えば。
main_dir
- temp_1
- temp_2
私の試み:
while [[ 1 ]]; do
printf "Which file do you want to use? ($(ls -m ${main_dir})) "
read -r ans
if [[ -d ${main_dir}/${ans} ]]; then
break
else
echo "[ERROR] Failed to choose. Please choose from ($(ls -m "${main_dir}"))."
fi
done
この場合、出力は次のようになります。
Which file do you want to use? (temp_1, temp_2)
また、ユーザーはファイルを選択するためにファイル名を入力する必要があります。
期待される結果:
Which file do you want to use?
1. temp_1
2. temp_2
また、ユーザーは名前またはインデックスを入力する両方の方法でファイルを選択できる必要があります。
答え1
* をループして、配列内のファイルを記憶します。
files=()
i=0
for f in *
do
[ -d "$f" ] && continue ## skip directoriries
files[$i]="$f"
echo "$i"$'\t'"${files[i]}"
(( ++i ))
done
if read -p "Which file do you want to use? " ans
then
echo "you choose ${files[ans]}"
stat "${files[ans]}"
wc "${files[ans]}"
fi
答え2
bash のディレクティブの有用性に関する @Cyrus のコメントを拡張しますselect
...
番号または名前で選択できるという条件がなければ、bash だけでselect
十分でしょう。
$ select name in *; do printf "You chose %s\n" "$name"; done
1) file AA 6) file_E 11) file_J 16) file_O 21) file_T 26) file_Y
2) file_A 7) file_F 12) file_K 17) file_P 22) file_U 27) file_Z
3) file_B 8) file_G 13) file_L 18) file_Q 23) file_V 28) foo.sh
4) file_C 9) file_H 14) file_M 19) file_R 24) file_W
5) file_D 10) file_I 15) file_N 20) file_S 25) file_X
#? 1
You chose file AA
#? 4
You chose file_C
#? 28
You chose foo.sh
#? ^D
インターフェースは、ニーズによってはやや質素すぎるかもしれませんが、素早く簡単に、しかもシェルグレードの信頼性が必要なときには、select
バッグに入れておくと便利なツールです。
man
bash のページには、利用できる の動作のいくつかの側面が引用されていますselect
。
次に PS3 プロンプトが表示され、
標準入力から 1 行が読み取られます。行が、
表示された単語の 1 つに対応する数字で構成されている場合、name の値は
その単語に設定されます。行が空の場合、単語とプロンプトが
再度表示されます。EOF が読み取られると、コマンドは完了します。その他
の値が読み取られると、name は null に設定されます。読み取られた行は、
変数 REPLY に保存されます。
したがって、 の呼び出しの周りにサポート コードを配置することでselect
、次のことが可能になります。
unset name
_PS3="$PS3"
PS3="Which file do you want to use? "
while [ -z "$name" ]
do
select name in *; do break; done
if [ -z "$name" ]
then
if [ -f "$REPLY" ]
then
name="$REPLY"
printf "You chose by name: '%s'\n" "$name"
else
printf "There is no file by that name.\n"
fi
else
printf "You chose by number: '%s'\n" "$name"
fi
done
PS3="$_PS3"; unset _PS3
出力:
$ ./foo.sh
1) file AA 6) file_E 11) file_J 16) file_O 21) file_T 26) file_Y
2) file_A 7) file_F 12) file_K 17) file_P 22) file_U 27) file_Z
3) file_B 8) file_G 13) file_L 18) file_Q 23) file_V 28) foo.sh
4) file_C 9) file_H 14) file_M 19) file_R 24) file_W
5) file_D 10) file_I 15) file_N 20) file_S 25) file_X
Which file do you want to use? 12
You chose by number: 'file_K'
$ ./foo.sh
1) file AA 6) file_E 11) file_J 16) file_O 21) file_T 26) file_Y
2) file_A 7) file_F 12) file_K 17) file_P 22) file_U 27) file_Z
3) file_B 8) file_G 13) file_L 18) file_Q 23) file_V 28) foo.sh
4) file_C 9) file_H 14) file_M 19) file_R 24) file_W
5) file_D 10) file_I 15) file_N 20) file_S 25) file_X
Which file do you want to use? file W
There is no file by that name.
1) file AA 6) file_E 11) file_J 16) file_O 21) file_T 26) file_Y
2) file_A 7) file_F 12) file_K 17) file_P 22) file_U 27) file_Z
3) file_B 8) file_G 13) file_L 18) file_Q 23) file_V 28) foo.sh
4) file_C 9) file_H 14) file_M 19) file_R 24) file_W
5) file_D 10) file_I 15) file_N 20) file_S 25) file_X
Which file do you want to use? 29
There is no file by that name.
1) file AA 6) file_E 11) file_J 16) file_O 21) file_T 26) file_Y
2) file_A 7) file_F 12) file_K 17) file_P 22) file_U 27) file_Z
3) file_B 8) file_G 13) file_L 18) file_Q 23) file_V 28) foo.sh
4) file_C 9) file_H 14) file_M 19) file_R 24) file_W
5) file_D 10) file_I 15) file_N 20) file_S 25) file_X
Which file do you want to use? file AA
You chose by name: 'file AA'