1

I have multiple Freesurfer exports with subdirectories named "stats" in each one. I want to run a bash script that searches for each "stats" folder then CDs in to it, runs a predefined perl script that converts specified stats files contained in each folder. I want them to run on each folder recursively. The stats folders are named with the MRI number then the date.

I was able to get the script to separate the MRIDATE, MIRIID and create files from inside the subfolder of one of the Exports. I cannot get it to work a subdirectory below.

#!/bin/bash
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"

for D in */*/*/stats/; do
    echo $D
    if [ -d "${D}" ]; then
cd "${D}"

cwd=$(pwd)
D2=$(dirname "$cwd")
#Capture second folder in MRI name and date
MRINAME=$(basename "$D2")
DIRNAME2=$(basename "$D2")/$(basename "$cwd")
MRIID="$(cut -d'_' -f1 <<<"$MRINAME")"
echo "$MRIID"
MRIDATE="$(cut -d'_' -f2 <<<"$MRINAME")"
echo "$MRIDATE"
/Users/xxxxx/Documents/Bitbucket\ Repository/conversion-scripts/mri-read.pl -d $MRIDATE -s $MRIID lh.aparc.stats rh.aparc.stats wmparc.stats aseg.stats
fi
done
Dennis Williamson
  • 346,391
  • 90
  • 374
  • 439
Brook Hurd
  • 37
  • 5
  • `IFS=_ read -r MRIID MRIDATE <<< "$MRINAME"`, but use `find ... -exec perlscript \;` instead of at least part this. And you should add some indentation. – Dennis Williamson Jun 07 '19 at 23:39
  • I made some modifications. I am able to get the command to run on the first folder found, but not the second or any more after that. – Brook Hurd Jun 07 '19 at 23:57
  • You need to `cd` back to the parent directory at the end of your `if` block. You can do that with `cd` in/`cd` out or `pushdir`/`popdir` or by wrapping the inside of the block (between `then` and `fi` in a subshell (parens). If that solves your whole problem, let me know and I'll post the contents of this comment as an answer. – Dennis Williamson Jun 08 '19 at 00:02
  • Why didn't I see that? That worked perfectly. – Brook Hurd Jun 08 '19 at 00:12
  • Don't edit your question to include the solution. That will cause confusion for future readers. – Dennis Williamson Jun 08 '19 at 00:14
  • Yes, sorry. I tried to make it better below. Is there a way to set For to find "stats" in any directory structure? I currently have to call the folder paths. – Brook Hurd Jun 08 '19 at 00:21
  • If you have a new enough version of Bash, you can do `shopt -s globstar` and use `**` to make the globs recursive. Look at the [Bash Manual](https://www.gnu.org/software/bash/manual/bash.html#Pattern-Matching) to learn more. – Dennis Williamson Jun 08 '19 at 00:29
  • That doesn't work. I am running this on a Mac so it may be a Mac restriction. – Brook Hurd Jun 08 '19 at 00:36
  • Macs are stuck on a more than 10 year old version of Bash (i.e ancient). They won't update because they don't like the license it has after that version (3.2). In fact, Apple is soon switching to zsh. You can install a current version of Bash using homebrew. – Dennis Williamson Jun 08 '19 at 00:40
  • 1
    Don't use all upper case letters for non-exported variables. See https://stackoverflow.com/questions/673055/correct-bash-and-shell-script-variable-capitalization – Ed Morton Jun 08 '19 at 01:07

2 Answers2

2

You need to cd back to the parent directory at the end of your if block. You can do that with cd in/cd out or pushd/popd or by wrapping the inside of the block (between then and fi) in a subshell (parens).

An example:

for dir in */
do
    # the if [ -d ... isn't necessary since the filespec in the for ends with a slash
    pushd "$dir" > /dev/null

    # other stuff

    popd > /dev/null
done
Dennis Williamson
  • 346,391
  • 90
  • 374
  • 439
1

I corrected the code in the initial question. It works perfectly.

#!/bin/bash
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"

for D in */*/*/stats/; do
    echo $D
    if [ -d "${D}" ]; then
cd "${D}"

cwd=$(pwd)
D2=$(dirname "$cwd")
#Capture second folder in MRI name and date
MRINAME=$(basename "$D2")
DIRNAME2=$(basename "$D2")/$(basename "$cwd")
MRIID="$(cut -d'_' -f1 <<<"$MRINAME")"
echo "$MRIID"
MRIDATE="$(cut -d'_' -f2 <<<"$MRINAME")"
echo "$MRIDATE"
"$DIR/mri-read.pl" -d $MRIDATE -s $MRIID lh.aparc.stats rh.aparc.stats wmparc.stats aseg.stats
cd "${DIR}"
fi
done
Brook Hurd
  • 37
  • 5