开发者

How do you store a list of directories into an array in Bash (and then print them out)?

I want to write a shell script to show a li开发者_开发百科st of directories entered by a user and then for a user to select one of the directories with an index number based on how many directories there are

I'm thinking this is some kind of array operation, but im not sure how to do this in shell script

example:

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


$ 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/!


Array syntax

Assuming you have the directories stored in an array:

dirs=(dir1 dir2 dir3)

You can get the length of the array thusly:

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

You can loop through it like so:

let i=1

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

And assuming you've gotten the user's answer, you can index it as follows. Remember that arrays are 0-based so the 3rd entry is index 2.

answer=2

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

Find

How do you get the file names into an array, anyways? It's a bit tricky. If you have find that might be the best way:

readarray -t dirs < <(find . -maxdepth 1 -type d -printf '%P\n')

The -maxdepth 1 stops find from looking through subdirectories, -type d tells it to find directories and skip files, and -printf '%P\n' tells it to print the directory names without the leading ./ it normally likes to print.


#! /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]}"


Update: my answer is wrong

Leaving it here to address a common misunderstanding, below the line is erroneous.


To put the directories in an array you can do...

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

This will capture the dir names, including those with spaces.


Extracting from comments:

literal quotes don't have any effect on string-splitting, so array=( echo '"hello world" "goodbye world"' ) is an array with four elements, not two

@Charles Duffy

Charles also supplied the following link Bash FAQ #50 which is an extended discussion on this issue.

I should also draw attention to the link posted by @Dennis Williamson - why I shouldn't have used ls

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜