LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   Simple bash array question (https://www.linuxquestions.org/questions/programming-9/simple-bash-array-question-4175460478/)

captdavid1949 05-02-2013 03:02 PM

Simple bash array question
 
Have found myself in the position of needing to write short simple bash script to create an array of directories.
Code:

#! /bin/bash
drives=(/run/media/david/*)
       
for i in "${drives[@]}";
        do
                echo $i
        done

exit

This script returns
/run/media/david/External_Drive_1
/run/media/david/Misc-Files
on seperate lines as expected.

What I need to do, (and have not been able to figure out) is to have echo $i return the directory names only, on seperate lines.

External_Drive_1
Misc-Files

Done my searching, but when I get far into the land of nested brackets and single vs double quotes I am wandering in the dark without a lantern.

TIA for any suggestions

unSpawn 05-02-2013 03:07 PM

'echo "${i//*\//}";' or 'echo "$(basename "$i")";'

captdavid1949 05-02-2013 03:36 PM

Thanks... If you have a moment can you explain ${i//*\//} for my further edification? I almost get why it works, but so simple (like the jitterbug) it has plumb evaded me.


Tks again

archShade 05-02-2013 05:12 PM

The ${i//*\//} first takes the value of i, the first double forward slash says relplace matching strings with another string. The *\/ is the string to match, the * matches any value, the \/ escapes to a literal /, so the string matches anything up to and including the last /. Everything after the last / is the string to replace, in this case it's blank. So the command finds anything that matches */ (that is anything and up to including the final slash) and replaces it with nothing.

captdavid1949 05-02-2013 05:26 PM

Thanks for the explanation ... It becomes clear

grail 05-02-2013 07:39 PM

And one more:
Code:

echo "${i##*/}"

David the H. 05-05-2013 10:05 AM

{ Edit: :doh: I think I mis-read the whole thing. Simple parameter substitution is indeed all that's needed to strip off the pathname of a file. I'll leave this up for posterity anyway. }


If you want to print only the directory names, all you need is one quick fix:

Code:

#!/bin/bash
drives=( /run/media/david/*/ )
       
for i in "${drives[@]}"; do
    echo "$i"
done

exit

(Note that I've cleaned up a few other small things too.)

"*" outputs all entries, but "*/" only expands directories.

Note also though that hidden directories are not expanded by default. You have to add shopt -s dotglob first to get those.

You can replace the above loop with a simple printf, by the way.

Code:

printf '%s\n' "${drives[@]}"
For more advanced filtering you'll have to run tests on the inputs first, or use find. If you wanted only regular files, for example, you'd need this:

Code:

drives=( /run/media/david/* )
       
for i in "${drives[@]}"; do
    [[ -f $i ]] && echo "$i"
done


captdavid1949 05-05-2013 10:18 AM

thanks again for all the input and suggestions.


All times are GMT -5. The time now is 01:36 AM.