Как сохранить список каталогов в массив в Bash (а затем распечатать их)?

Я хочу написать оболочку script, чтобы показать список каталогов, введенных пользователем, а затем пользователю выбрать один из каталогов с номером индекса в зависимости от количества каталогов

Я думаю, что это какая-то операция с массивом, но я не уверен, как это сделать в оболочке script

Пример:

> whichdir
There are 3 dirs in the current path
1 dir1
2 dir2
3 dir3
which dir do you want? 
> 3
you selected dir3!

Ответы

Ответ 1

$ ls -a
./ ../ .foo/ bar/ baz qux*
$ shopt -s dotglob
$ shopt -s nullglob
$ array=(*/)
$ for dir in "${array[@]}"; do echo "$dir"; done
.foo/
bar/
$ for dir in */; do echo "$dir"; done
.foo/
bar/
$ PS3="which dir do you want? "
$ echo "There are ${#array[@]} dirs in the current path"; \
select dir in "${array[@]}"; do echo "you selected ${dir}"'!'; break; done
There are 2 dirs in the current path
1) .foo/
2) bar/
which dir do you want? 2
you selected bar/!

Ответ 2

Синтаксис массива

Предполагая, что у вас есть каталоги, хранящиеся в массиве:

dirs=(dir1 dir2 dir3)

Вы можете получить длину массива:

echo "There are ${#dirs[@]} dirs in the current path"

Вы можете пропустить его так:

let i=1

for dir in "${dirs[@]}"; do
    echo "$((i++)) $dir"
done

И если вы получили ответ пользователя, вы можете индексировать его следующим образом. Помните, что массивы основаны на 0, поэтому 3-я запись - это индекс 2.

answer=2

echo "you selected ${dirs[$answer]}!"

Найти

Как вы получаете имена файлов в массив, так или иначе? Это немного сложно. Если вы обнаружите, что это лучший способ:

dirs=( $(find . -maxdepth 1 -type d -printf '%P\n') )

-maxdepth 1 перестает находить поиск в подкаталогах, -type d сообщает ему, что он находит каталоги и пропускает файлы, а -printf '%P\n' сообщает ему распечатать имена каталогов без ведущего ./, который обычно нравится печатать.

Ответ 3

#! /bin/bash

declare -a dirs
i=1
for d in */
do
    dirs[i++]="${d%/}"
done
echo "There are ${#dirs[@]} dirs in the current path"
for((i=1;i<=${#dirs[@]};i++))
do
    echo $i "${dirs[i]}"
done
echo "which dir do you want?"
echo -n "> "
read i
echo "you selected ${dirs[$i]}"

Ответ 4

Bash теперь поддерживает одномерные массивы. Поскольку массивы не обязательно должны иметь смежные элементы, они больше похожи на карты.

Ответ 5

Чтобы разместить каталоги в массиве, вы можете сделать...

array=( $( ls -1p | grep / | sed 's/^\(.*\)/"\1"/') )

Это приведет к захвату имен dir, включая те, в которых есть пробелы.