
Ich habe mehrere Dateien in einem Verzeichnis und arbeite an einem Bash-Skript, um alle Dateien zusammen mit einem Index daneben aufzulisten, sodass die Benutzer anhand des Indexes auswählen können, welche Datei sie auswählen möchten, anstatt den gesamten Dateinamen zu schreiben.
Zum Beispiel:
main_dir
- temp_1
- temp_2
Mein Versuch:
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
In diesem Fall lautet die Ausgabe:
Which file do you want to use? (temp_1, temp_2)
Außerdem muss der Benutzer den Namen der Datei eingeben, um sie auszuwählen.
ERWARTETES ERGEBNIS:
Which file do you want to use?
1. temp_1
2. temp_2
Außerdem sollte der Benutzer eine Datei auf beide Arten auswählen können: durch Eingabe des Namens oder des Index.
Antwort1
Schleife über * und merke dir die Dateien in einem Array:
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
Antwort2
Erweiterung des Kommentars von @Cyrus zur Nützlichkeit der Bash- select
Direktive …
Wenn Ihre Bedingung, nach Nummer oder Name auswählen zu können, nicht wäre, select
wäre die Option von Bash möglicherweise alles, was Sie brauchen:
$ 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
Obwohl die Benutzeroberfläche für manche Zwecke etwas spartanisch sein könnte, ist es ein nützliches Werkzeug, das man in der Tasche haben sollte, wenn man etwas Schnelles und Einfaches braucht, das aber dennoch zuverlässig ist .
Auf der man
Seite für Bash werden einige Aspekte des select
Verhaltens von aufgeführt, die wir nutzen können:
Anschließend wird die PS3-Eingabeaufforderung angezeigt und eine Zeile aus der
Standardeingabe gelesen. Wenn die Zeile aus einer Zahl besteht, die
einem der angezeigten Wörter entspricht, wird der Wert von name auf
dieses Wort gesetzt. Wenn die Zeile leer ist, werden die Wörter und die Eingabeaufforderung
erneut angezeigt. Wenn EOF gelesen wird, wird der Befehl abgeschlossen. Jeder
andere gelesene Wert führt dazu, dass name auf null gesetzt wird. Die gelesene Zeile
wird in der Variablen REPLY gespeichert.
Indem wir den Aufruf von mit etwas unterstützendem Code umgeben select
, ist Folgendes möglich:
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
Ausgabe:
$ ./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'