Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Loop over directories with whitespace in Bash

Tags:

bash

In a bash script, I want to iterate over all the directories in the present working directory and do stuff to them. They may contain special symbols, especially whitespace. How can I do that? I have:

for dir in $( ls -l ./)
do
    if [ -d ./"$dir" ]

but this skips my directories with whitespace in their name. Any help is appreciated.

like image 699
jakev Avatar asked Feb 04 '11 07:02

jakev


People also ask

What does [- Z $1 mean in bash?

$1 means an input argument and -z means non-defined or empty. You're testing whether an input argument to the script was defined when running the script. Follow this answer to receive notifications.

Does Bash care about whitespace?

If you don't care much about whitespace bash is great: it normally turns multiple whitespace characters into one and it breaks things into words based on white space. If on the other hand you'd like to preserve whitespace bash can be a bit difficult at times.

How do you loop a directory in Linux?

We use a standard wildcard glob pattern '*' which matches all files. By adding a '/' afterward, we'll match only directories. Then, we assign each directory to the value of a variable dir. In our simple example, we then execute the echo command between do and done to simply output the value of the variable dir.


3 Answers

Give this a try:

for dir in */
like image 108
Dennis Williamson Avatar answered Sep 20 '22 13:09

Dennis Williamson


Take your pick of solutions:

http://www.cyberciti.biz/tips/handling-filenames-with-spaces-in-bash.html

The general idea is to change the default seperator (IFS).

#!/bin/bash
SAVEIFS=$IFS
IFS=$(echo -en "\n\b")
for f in *
do
  echo "$f"
done
IFS=$SAVEIFS
like image 24
SpliFF Avatar answered Sep 20 '22 13:09

SpliFF


There are multiple ways. Here is something that is very fast:

find /your/dir -type d -print0 | xargs -0 echo

This will scan /your/dir recursively for directories and will pass all paths to the command "echo" (exchange to your need). It may call echo multiple time, but it will try to pass as many directory names as the console allows at once. This is extremely fast because few processes need to be started. But it works only on programs that can take an arbitrary amount of values as options. -print0 tells find to seperate file paths using a zero byte (and -0 tells xargs to read arguments seperated by zero byte) If you don't have the later one, you can do this:

find /your/dir -type d -print0 | xargs -0 -n 1 echo

or

find /your/dir -type d -print0 --exec echo '{}' ';'

The option -n 1 will tell xargs not to pass more arguments than one at the same time to your program. If you don't want find to scan recursively you can specify the depth option to disable recursion (don't know the syntax by heart though).

Though if that's usable in your particular script is another question ;-).

like image 34
yankee Avatar answered Sep 19 '22 13:09

yankee