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

后端 未结 4 716
别那么骄傲
别那么骄傲 2020-12-05 09:52

I want to write a shell script to show a list 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 di

相关标签:
4条回答
  • 2020-12-05 10:11
    #! /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]}"
    
    0 讨论(0)
  • 2020-12-05 10:13

    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.

    0 讨论(0)
  • 2020-12-05 10:30

    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 讨论(0)
  • 2020-12-05 10:32
    $ 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/!
    
    0 讨论(0)
提交回复
热议问题