我想写一个shell脚本来显示用户输入的目录列表,然后让用户根据有多少目录选择一个索引号的目录
我认为这是某种数组操作,但我不确定如何在shell脚本中执行此操作
示例:
> whichdir
There are 3 dirs in the current path
1 dir1
2 dir2
3 dir3
which dir do you want?
> 3
you selected dir3!
答案 0 :(得分:39)
$ 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/!
答案 1 :(得分:21)
假设您将目录存储在数组中:
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]}!"
无论如何,如何将文件名转换为数组?这有点棘手。如果你有find
可能是最好的方式:
readarray -t dirs < <(find . -maxdepth 1 -type d -printf '%P\n')
-maxdepth 1
通过子目录查找停止查找,-type d
告诉它查找目录并跳过文件,-printf '%P\n'
告诉它打印没有前导{{1}的目录名称它通常喜欢打印。
答案 2 :(得分:4)
#! /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]}"
答案 3 :(得分:1)
Bash现在支持single-dimensional arrays。因为数组不需要具有连续元素,所以它们看起来更像地图。
答案 4 :(得分:-1)
要将目录放在数组中,您可以执行...
array=( $( ls -1p | grep / | sed 's/^\(.*\)/"\1"/') )
这将捕获目录名称,包括带空格的名称。
从评论中摘录:
字面引号对字符串分割没有任何影响,所以array =(echo'“hello world”“goodbye world”')是一个包含四个元素的数组,而不是两个
Charles还提供了以下链接Bash FAQ #50,这是对此问题的扩展讨论。
我还应该注意@Dennis Williamson发布的链接 - why I shouldn't have used ls