0

This question already has an answer here:

I want to archive my photos into tar archives.

The directory containing photos has one dir per year and multiple dirs inside each year dir:

Photos
    2005
    2006
        Some dir with spaces
            Pic1.jpg
            Pic2.jpg
            ...
        Other dir here
        ...
    2007
    ...

Target structure should also contain a directory per year, but inside a year dir I would have tar.gz files for each subdir from source dir, like this:

Backup
    2005
    2006
        Some_dir_with_spaces.tar.gz
        Other_dir_here.tar.gz
        ...
    2007
    ...

Script which I'm creating to do this looks as follows:

cd ~/Photos
for y in *
do
    YEAR_DIR=~/Backup/$y
    mkdir -p $YEAR_DIR

    pushd $y

    for d in *
    do
        f=`echo $d | tr ' ' '_' | tr -d ',.!'`  # Clean the name
        t=$YEAR_DIR/$f.tar.gz
        d=$(printf '%q' "$d")
        # echo tar czf $t "$d"  # This outputs the command as expected
        tar czf $t "$d"  # but executing it results in error: Cannot stat: No such file or directory
    done

    popd
done

As hinted in the comment, echoing the prepared command looks fine, and also if I copy that statement and execute it from terminal it works, but executing it within the script (tar czf $t "$d") results in an error:

tar: Some\ dir\ with\ spaces: Cannot stat: No such file or directory

What am I doing wrong?

P.S. I'm doing this on a Mac.

marked as duplicate by Gilles shell-script May 3 '16 at 23:06

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

  • You might want to look at using d=${d/ /_} to do replacement of spaces in variables (assuming you're using bash) – Anthon May 3 '16 at 6:31
2

You are using printf to escape the spaces, as well as quoting it ""

If you omit the printf call, and use the original $d with double-quotes, you are good.

    f=`echo $d | tr ' ' '_' | tr -d ',.!'`  # Clean the name
    t=$YEAR_DIR/$f.tar.gz
    ##d=$(printf '%q' "$d") escapes the spaces
    # echo tar czf $t "$d"  # This outputs the command as expected
    tar czf $t "$d" ## "$d" also escapes the spaces
  • Cleaned file name is used to create the archive file name ($t) and it does not exist as a dir name. I cannot use it as a second parameter to tar, because I have to pass original dir name to be archived into tar. That's why I'm passing in $d. – Anil May 3 '16 at 5:17
  • see if the edited solution works for you :) – Nathan Boolean Trujillo May 3 '16 at 5:40
  • 1
    Yes, that's the part I wasn't seeing. On the path to the solution I've left too much crap behind :-) – Anil May 3 '16 at 5:58

Not the answer you're looking for? Browse other questions tagged or ask your own question.