如何在Bash中将目录列表存储到数组中(然后将其打印出来)?

时间:2010-12-20 21:55:49

标签: arrays bash directory

我想写一个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!

5 个答案:

答案 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 Duffy

Charles还提供了以下链接Bash FAQ #50,这是对此问题的扩展讨论。

我还应该注意@Dennis Williamson发布的链接 - why I shouldn't have used ls