1

I am attempting to write a bash script that operates on each directory in a subset. Unfortunately the path contains spaces, and I am unable to change the name.

The for loop insists on breaking at each space; I have tried dozens of variants, but am unable to come up with a solution.

A simplified version is below.

#!/bin/bash
SOURCE="/Volumes/Time Machine Backups/Backups.backupdb/Zaphod"
for file in `ls -d "$SOURCE"/201*`
do
    echo "File: $file"
done

Can anyone suggest how I can get every entry e.g. /Volumes/Time Machine Backups/Backups.backupdb/Zaphod/2017-06-30-215735 in a separate variable.

Milliways
  • 1,378

2 Answers2

2

The least change solution is:

#!/bin/bash
SOURCE="/Volumes/Time Machine Backups/Backups.backupdb/Zaphod"
for file in "$SOURCE"/201*
do
    echo "File: $file"
done

An alternative (if you have no problem on changing the positional parameters):

#!/bin/bash
SOURCE="/Volumes/Time Machine Backups/Backups.backupdb/Zaphod"
set -- "$SOURCE"/201*
for file; do
    echo "File: $file"
done

A more precise solution that avoids directories and works on file with spaces (but not newlines):

ls -dp "$a"/201* | grep -v '/$' | 
    while read f; do echo "File:$f"; done

Or a solution that works for any name, but that also may list dot-files (if the name match):

find "$a" -type f -name "201*" -exec echo "File: {}" \;
0

If no spaces in files in directory:

#!/bin/bash
SOURCE="/Volumes/Time Machine Backups/Backups.backupdb/Zaphod"
cd "$SOURCE"
for file in $(ls -d ./201*)
do
    echo "File: $file"
done

if unsure about spaces being in the directory list or not, do this instead:

#!/bin/bash
SOURCE="/Volumes/Time Machine Backups/Backups.backupdb/Zaphod"
cd "$SOURCE"
shopt -s nullglob
for filename in 201*;do
   if [[ ! -d "$filename" ]];then
      echo "$filename"
   fi
done
shopt -u nullglob

I'm not clear if you want directory file names or not, if not, this is what works.

The second is the generally preferred solution when you don't know if there are spaces or not I believe.

Lizardx
  • 3,058
  • 17
  • 18