Dynamically execute functions in different folders using bash - bash

I have two folders: control and patients both with several folders inside, belonging to one individual each.
I want to do two things:
Create inside the folder for each individual a new folder called cortical_maks and inside that one, three more, called accumebens, putamen, caudate
Inside each individual folder, there are images in img format I want to convert to nii.gz using the funtion fslchfiletype.
This is what I have so far:
DIR="/media/Roy"; cd "$DIR/Analysis"
for group in Controls Patients; do
for case in $group/*; do
[ -d $case ] || continue #if its not a folder
mkdir $DIR/Analysis/$case/Cortical_masks && cd $_
mkdir accumbens putamen caudate
for file in $DIR/Analysis/$case/ROIS2/rs_roi/*.img; do
fslchfiletype NIFTI_GZ "$file"
done;
done;
done;
There are two problems with this code.
The second time you run it, the folder cortical masks is created in the main folders, that is controls and patients, that is, outside the folder it´s supposed to work.
Also, it just converts img to niig.gz for one folder at a time. First time you execute the script, converts imgs for the folder belonging to the first individual, etc

Question 01 :
The second time you run it, the folder cortical masks is created in the main folders, that is controls and patients. I want it in a way that doesn´t create new folders if there is already one with the same name.
I suggest you to use an if loop to verify if the folder cortical_mask exist before to run your code :
#check if the folder exist, if yes = true so we add ! caracter to have the opposite
if [ ! -d "$DIR/Analysis/$case/Cortical_masks" ]
then
#Your code
fi
Question 02 :
Also, it just converts img to niig.gz for one folder at a time. First time you execute the script, converts imgs for the folder belonging to the first individual, etc
If you want to do two actions in the same time, why do you not create two bash scripts and execute them simulteanously ? Or, you can automate them by creating a process in your OS which will execute scripts for you.

Related

Looking for a script to move files into folders based on a variable in the filename

I have a folder of images I would like to automatically organize into sub folders based on a variable in the filenames. I'm new to scripting and I've tried to best explain what I would like below:
For example:
If files contains "BO" then create new folder called "Boucle" in same directory then add files that contain "BO"
If files contains "CW" then create new folder called "Cross" in same directory then add files that contain "CW"
I would like to run this in Automator and have some ability to add new variables in the future
Ideally, the creation of these new sub folders can happen in the same directory location I feed into the script.
Thank you!
I've tried some basic scripting but I think the variables are throwing me
for f in "$#"
do
if [[$f == "BO"]]
then
mkdir in "$#" "${BOUCLE WOOL}"
fi
done

How to create a list of sequentially numbered folders using an existing folder name as the base name

I've done a small amount of bash scripting. Mostly modifying a script to my needs.
On this one I am stumped.
I need a script that will read a sub-folder name inside a folder and make a numbered list of folders based on that sub-folder name.
Example:
I make a folder named “Pictures”.
Then inside I make a sub-folder named “picture-set”
I want a script to see the existing sub-folder name (picture-set) and make 10 more folders with sequential numbers appended to the end of the folder names.
ex:
folder is: Pictures
sub-folder is: picture-set
want to create:
“picture-set-01”
“picture-set-02”
“picture-set-03”
and so forth up to 10. Or a number specified in the script.
The folder structure would look like this:
/home/Pictures/picture-set
/home/Pictures/picture-set-01
/home/Pictures/picture-set-02
/home/Pictures/picture-set-03
... and so on
I am unable to tell the script how to find the base folder name to make additional folders.
ie: “picture-set”
or a better option:
Would be to create a folder and then create a set of numbered sub-folders based on the parent folder name.
ex:
/home/Songs - would become:
/home/Songs/Songs-001
/home/Songs/Songs-002
/home/Songs/Songs-003
and so on.
Please pardon my bad formatting... this is my first time asking a question on a forum such as this. Any links or pointers as to proper formatting is welcome.
Thanks for the help.
Bash has a parameter expansion you can use to generate folder names as arguments to the mkdir command:
#!/usr/bin/env bash
# Creates all directories up to 10
mkdir -p -- /home/Songs/Songs-{001..010}
This method is not very flexible if you need to dinamically change the range of numbers to generate using variables.
So you may use a Bash for loop and print format the names with desired number of digits and create each directory in the loop:
#!/usr/bin/env bash
start_index=1
end_index=10
for ((i=start_index; i<=end_index; i++)); do
# format a dirpath with the 3-digits index
printf -v dirpath '/home/Songs/Songs-%03d' $i
mkdir -p -- "$dirpath"
done
# Prerequisite:
mkdir Pictures
cd Pictures
# Your script:
min=1
max=12
name="$(basename "$(realpath .)")"
for num in $(seq -w $min $max); do mkdir "$name-$num"; done
# Result
ls
Pictures-01 Pictures-03 Pictures-05 Pictures-07 Pictures-09 Pictures-11
Pictures-02 Pictures-04 Pictures-06 Pictures-08 Pictures-10 Pictures-12

How to iterate between directories in shell script

I want to convert images from .img to .nii.gz using the function fslchfiletype.
These images are stored in Controls and Patients folders, each one of this folders have several folders belonging to each one of the individuals, like C01, C02, , etc. Specifically, each one of the individuals has the .img files inside a folder called rs_roi, which is inside another folder called ROIS2. This is what I have:
DIR="/media/Roy"; cd "$DIR/Analysis"
for group in Controls Patients; do
for case in $group; do
mkdir $DIR/Analysis/$group/$case/Cortical_masks
for file in $DIR/Analysis/$group/$case/ROIS2/rs_roi/.img; do
fslchfiletype NIFTI_GZ "$file"
done;
done;
done;
Notice how I also want to create a folder called Cortiical_maks inside each and one of the individuals.
This gives me the next error:
mkdir: cannot create directory ´media/Roy/Analysis/Controls/Controls/Cortical_masks´: No such file or directory.
Cannot open volume media/Roy/Analysis/Controls/Controls/ROIS2/rs_roi/ for reading!
mkdir: cannot create directory ´media/Roy/Analysis/Patients/Patients/Cortical_masks´: No such file or directory.
Cannot open volume media/Roy/Analysis/Patients/Patients/ROIS2/rs_roi/ for reading!
It´s iterating two times the Controls Patients folder: Control/Control. Maybe the problem is here for case in $group; do? Thx
Once you have your directory name assigned to a variable, you have to glob the directory to get its contents. Otherwise, as you saw, $group is not expanded, and you're only looping over that single term itself.
You might also like to check that each entry is indeed a directory before you traverse into it.
for case in $group/*; do
[ -d $case ] || continue
mkdir $DIR/Analysis/$group/$case/Cortical_masks
for file in $DIR/Analysis/$group/$case/ROIS2/rs_roi/.img; do
fslchfiletype NIFTI_GZ "$file"
done;
done;
You should probably also quote your variables in more places, unless you are sure they don't need quoting. I always lint my scripts with shellcheck to get that kind of advice.
I made a small change to #Noah answer, this script works fine:
for group in Controls Patients; do
for case in $group/*; do
[ -d $case ] || continue
mkdir $DIR/Analysis/$case/Cortical_masks
for file in $DIR/Analysis/$case/ROIS2/rs_roi/*.img; do
fslchfiletype NIFTI_GZ "$file"
done;
done;
done;
I deleted $group in both paths, and added * in *.img which i forgot.

Nesting a case statement within a for loop

I'm trying to follow the instructions below in order to create one directory containing four subdirectories inside, each of these latter with five new empty files:
Create a directory with the name of the first positional parameter (choose whatever name you want).
Use a for loop to do the following:
2.1. Within the directory, create four subdirectories with these names: rent, utilities, groceries, other.
2.2. Within the for loop, use case statements to determine which subdirectory is currently being handled in the loop. You will need 4
cases.
2.3. Within each case, use a for loop to create 5 empty files with the touch command. Each subdirectory must have its 5 files inside.
So far, I have created a directory and several subdirectories at once, each of them with a specific name, as you can see in my code:
mkdir $1
for folder in $1; do
mkdir -p $1/{Rent,Utilities,Groceries,Other}
done
However, I'm stuck in the following step (2.2.), and I don't know how to continue from here.
Any ideas?
As I read it, this is what 2.1 and 2.2 are asking for:
for folder in rent utilities groceries other; do
mkdir "$1/$folder"
case $folder in
rent)
...
;;
utilities)
...
;;
groceries)
...
;;
other)
...
;;
esac
done
I've left the cases blank for you to fill out.
For what it's worth, I would never code a script this way. Having a case statement inside a for loop is an anti-pattern. The loop really adds no value. If this weren't an assignment I would code it differently:
mkdir "$1"
# Populate rent/ directory.
mkdir "$1"/rent
touch "$1"/rent/...
# Populate utilities/ directory.
mkdir "$1"/utilities
touch "$1"/utilities/...
# Populate groceries/ directory.
mkdir "$1"/groceries
touch "$1"/groceries/...
# Populate other/ directory.
mkdir "$1"/other
touch "$1"/other/...

How to set automator (mac) to create folders and fill them with x number of files?

I have seen several variations of this question asked however none of witch fully answer my problem. I have several folders that contain between 2,000 and 150,000 image files. Searching these directories becomes very inefficient as the number of files increases as speed is drastically decreased.
What I want to do is use automator to:
1. select folder
2. create subfolder
3. fill newly created subfolder with the first 1000 files in the folder selected in (1.)
4. if more files exist in the outer folder, create another subfolder and fill with the next 1000 files etc.
Is this possible? Any help is much apreciated.
Thank you,
Brenden
This takes a directory and moves the contents to new folders called "newFolder1", "newFolder2" etc.
Have you used Terminal much? Let me know if you need more instruction. I also haven't put in any checks, so let me know if you get any errors.
o Save this file to your desktop (as script.sh for the purpose of tutorial)
#!/bin/bash
cd "$1" #Change directory to the folder to sort
filesPerFolder=$2 #This is how many files will be in each folder
currentDir='newFolder1';
currentFileCount=0;
currentDirCount=1;
mkdir $currentDir;
for file in *
do
if [ -f "$file" ]
then
mv "$file" "$currentDir";
fi
currentFileCount=$(($currentFileCount + 1));
if [ $(($currentFileCount % $filesPerFolder)) -eq "0" ] #Every X files, make a new folder
then
currentDirCount=$(($currentDirCount + 1));
currentDir='newFolder'$currentDirCount;
mkdir "$currentDir";
fi
done
o Open Terminal and type cd ~/Desktop/
o Type chmod 777 script.sh to change the permissions on the file
o Type ./script.sh "/path/to/folder/you/want/to/sort" 30
o The 30 here is how many files you want in each folder.

Resources