2

I have a task recently but it turns out harder than I thought.

  1. I need to find all the folders that match the pattern (Adobe Photoshop CC) in the /Applications/ directory.

  2. Then I create a folder, for example Test, in a directory that has the highest year number matching /Applications/Adobe Photoshop CC ????/Dummy-test/Test/.

  3. After that I move folder PSD from /private/tmp/com.example.test/PSD to the folder Test /Applications/Adobe Photoshop CC 2021/Dummy-test/Test/

  4. I want to give a note that folder Test may have been created earlier as well.

Here is the example folder structure:

Applications
|
|--- Adobe Photoshop CC 2015.5
|--- Adobe Photoshop CC 2019
|--- Adobe Photoshop CC 2021
|--- Adobe Photoshop CC 2014

I've tried this

#!/bin/sh

mkdir -p /Applications/Adobe\ Photoshop\ CC\ */Dummy-test/Test
mv /private/tmp/com.example.test/PSD /Applications/Adobe\ Photoshop\ CC\ */Dummy-test/Test/

and this

#!/bin/sh

INSTALL_DIRS = (/Applications/Adobe\ Photoshop\ СС\ */Dummy-test)
INSTALL_DIR=${INSTALL_DIRS[$((${#INSTALL_DIRS[@]}-1))]}
mkdir -p "$INSTALL_DIR"/"Test"

mv /private/tmp/com.example.test/PSD /Applications/Adobe\ Photoshop\ CC\ */Dummy-test/Test/

Obviously I need to learn more about the topic to be able to accomlish such tasks (maybe some books recommendations about shell scripting?). I need this script, so an experienced help would be much appreciated. Thank you.

3
  • @alecxs You can use array in shell scripts, and there is nothing here that calls for find. Feb 4, 2021 at 23:50
  • @alecxs Yes, but the context was a bash script, not a POSIX sh script. And even in POSIX sh, there is one array ("$@"). It's annoying because there's only one at a time, but `set -- /Applications/Adobe\ Photoshop\ CC\ *`` would be the best way to do this in POSIX sh. Feb 4, 2021 at 23:54
  • dir=$(ls -d /Applications/Adobe\ Photoshop\ CC\ */ | tail -n1); test -d "$dir" && mkdir -p "${dir}Dummy-test/Test" && mv /private/tmp/com.example.test/PSD "${dir}Dummy-test/Test" || exit 1
    – alecxs
    Feb 5, 2021 at 8:58

1 Answer 1

1

/Applications/Adobe\ Photoshop\ CC\ * enumerates the Adobe Photoshop CC directories you want. But /Applications/Adobe\ Photoshop\ CC\ */Dummy-test/Test enumerates existing Test directories. Passing wildcards to a command that will create the given files can't work. You need to separate the instruction to enumerate existing files from the instruction to create new files.

In your second attempt, remove the spaces around the equal sign. An assignment can't have spaces on either side of the equal sign. And again, unless Dummy-test already exists, INSTALL_DIRS won't end up with anything.

#!/bin/bash
shopt -s nullglob
photoshop_dirs=(/Applications/Adobe\ Photoshop\ СС\ *)
if ((${#photoshop_dirs[@]} == 0)); then
  echo >&2 "$0: fatal error: Adobe Photoshop CC is not installed."
  exit 1
fi
install_dir=${photoshop_dirs[$((${#photoshop_dirs[@]}-1))]}/Dummy-test/Test
mkdir -p "$install_dir"
mv /private/tmp/com.example.test/PSD "$install_dir/"

Explanations:

  • shopt -s nullglob causes the array to be empty if the wildcard pattern matches nothing. By default, wildcard patterns are unchanged if they match nothing, so the array would contain one element which is the unchanged pattern with the * in it.
  • I added a check to stop with an error message if no suitable directory exists.

If you're only interested in running scripts on macOS and on systems you control, I recommend using zsh rather than bash. Zsh is nicer and less error-prone. The advantage of bash is that it's installed by default on Linux and usually on *BSD too, whereas zsh is easy to install but usually not installed by default. On macOS, bash is a very old version, whereas zsh is installed by default and kept up-to-date.

#!/bin/zsh
setopt null_glob
photoshop_dirs=(/Applications/Adobe\ Photoshop\ СС\ *)
if (($#photoshop_dirs == 0)); then
  echo >&2 "$0: fatal error: Adobe Photoshop CC is not installed."
  exit 1
fi
install_dir=${photoshop_dirs[-1]}/Dummy-test/Test
mkdir -p $install_dir
mv /private/tmp/com.example.test/PSD $install_dir/
4
  • Thank you very much for such an extensive answer. I don't know how but somehow I didn't manage to make it work. fatal error: Adobe Photoshop CC is not installed. The Photoshop is installed. I tried even with zsh but can't make it work. What am I doing wrong?
    – Vlad K.
    Feb 5, 2021 at 1:51
  • I double-checked paths to files, all are correct. I was sure it should work. Can't understand why the script is not working for me.
    – Vlad K.
    Feb 5, 2021 at 2:11
  • I figured out why your code didn't work. Everything is correct except one thing – you forgot to put a list of the members parameter [@] in install_dir=${photoshop_dirs[$((${#photoshop_dirs[@]}-1))]} line. Without this parameter, it just split paths into separate words. Thank you very much for your help this code saved me a lot of time and it works like a charm!
    – Vlad K.
    Feb 5, 2021 at 8:20
  • 1
    Thanks, I fixed that and also some stray parentheses in the zsh version. Feb 5, 2021 at 15:06

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .