Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I get a list of directories in bash and then expand them as command line parameters?

I'm writing a bash script which needs to, for one step, get a list of directories (variable) in a target directory (which may also contain files), and then expand them out as parameters to a python script.

Example:

/stuff/a dir/
/stuff/b other/
/stuff/c/

And I need to, within a bash script, call:

script.py "a dir/" "b other/" "c/"

or alternately, escaped spaces:

script.py a\ dir/ b\ other/ c/

I need the script to be called exactly once for directory 'stuff'.

Is there a straightforward way to do this kind of thing? I've been googling around and the best I've managed to figure out requires me to know how many directories there are.

like image 898
Charles Randall Avatar asked Jun 24 '11 02:06

Charles Randall


People also ask

How do I list all directories in Bash?

Use the ls Command to List Directories in Bash. We use the ls command to list items in the current directory in Bash. However, we can use */ to print directories only since all directories finish in a / with the -d option to assure that only the directories' names are displayed rather than their contents.

How do I get a list of directories in terminal?

To see them in the terminal, you use the "ls" command, which is used to list files and directories. So, when I type "ls" and press "Enter" we see the same folders that we do in the Finder window.

Which command is used to show the list of all directories?

The ls command is used to list files or directories in Linux and other Unix-based operating systems. Just like you navigate in your File explorer or Finder with a GUI, the ls command allows you to list all files or directories in the current directory by default, and further interact with them via the command line.

How do I list only directories in Linux?

How can I list directories only in Linux? Linux or UNIX-like system use the ls command to list files and directories. However, ls does not have an option to list only directories. You can use combination of ls command, find command, and grep command to list directory names only.


1 Answers

This is a job for find.

find /stuff -type d -exec script.py {} +

When you use -exec the curly braces {} are replaced with the names of the matching files, and + indicates the end of the command (in case you want to tell find to take additional actions). This is the ideal way to execute a command using find as it will handle file names with unusual characters (such as whitespace) correctly.

find is quite flexible, especially if you have the GNU version typically bundled with Linux distros.

# Don't recurse into subdirectories.
find /stuff -maxdepth 1 -type d -exec script.py {} +

# Pass in a/, b/, c/ instead of /stuff/a/, /stuff/b/, /stuff/c/.
find /stuff -type d -printf '%P\0' | xargs -0 script.py

In the second example notice the careful use of \0 and xargs -0 to use the NUL character to delimit file names. It might seem odd but this allows the command to work even if you do something really weird like use newlines \n in your directory names.


Alternatively, you could do this using only shell builtins. I don't recommend this, but for educational value, here's how:

# Start with an empty array.
DIRS=()

# For each file in /stuff/...
for FILE in /stuff/*; do
    # If the file is a directory add it to the array. ("&&" is shorthand for
    # if/then.)
    [[ -d $FILE ]] && DIRS+=("$FILE")

    # (Normally variable expansions should have double quotes to preserve
    # whitespace; thanks to bash magic we don't them inside double brackets.
    # [[ ]] has special parsing rules.)
done

# Pass directories to script. The `"${array[@]}"` syntax is an unfortunately
# verbose way of expanding an array into separate strings. The double quotes
# and the `[@]` ensure that whitespace is preserved correctly.
script.py "${DIRS[@]}"
like image 73
John Kugelman Avatar answered Nov 15 '22 19:11

John Kugelman