How can i create sub directories within a directory? - shell

I am trying to make a photo organizer with a zsh shell script. But i am having trouble creating sub directories within each main directory(based on date). Currently the script starts from a folder i created and gets one argument(the file it needs to edit, hence the first cd $1). Secondly, i do some name changing which is irrelevant for my question. Next i create a directory for each date and move the photo to the correct directory.
The issue is, i want to loop through each date folder and make 2 new sub directories(jpg and raw). But when i run the code i get an error that there is no such file or directory..
Here is my current script:
#!/bin/zsh.
cd $1
for i in *.JPG;
do
mv $i $(basename $i .JPG).jpg;
done
for i in *;
do
d=$(date -r "$i" +%d-%m-%Y)
mkdir -p "$d"
mv -- "$i" "$d/";
done
for d in *;
do
cd $d
for i in *.jpg;
do
mkdir -p "jpg"
mv -- "$i" "jpg";
done
for i in *.NEF;
do
mkdir -p "raw"
mv -- "$i" "raw";
done
done
If anyone knows where i made a mistake that would be really helpfull since i have no clue what goes wrong and there is no debugger in nano as far as i know.

Related

bash script to create folder from filename and move two kinds of file into it

I have a set of banners that include .jpg and .psd. I need to create folder for them and move them into it.
example:
Banner-A.jpg
Banner-A.psd
Banner-B.jpg
Banner-B.psd
Banner-C.jpg
Banner-C.psd
Create folder and move them:
Banner-A/Banner-A.jpg Banner-A.psd
Banner-B/Banner-B.jpg Banner-B.psd
Banner-C/Banner-C.jpg Banner-C.psd
I manage to find a script here that work for the first part but I can't get the .psd to move as well.
for f in "$#"; do
cd "$f"
for file in *.jpg; do
folder=$(basename "$file" ".jpg")
mkdir -p "$folder" && mv "$file" "$folder"
done
done
Change your mv command to use the * wildcard as follows:
for file in *.jpg; do
folder=$(basename "$file" ".jpg")
mkdir -p "${folder}" && mv "${folder}".* "${folder}"
done
Make sure the .* is outside the quotes and it should work.
Example script:
#!/bin/bash
set -uo pipefail
doWork() {
dir="${1}"
cd "${dir}" || return
for file in *.jpg; do
folder=$(basename "$file" ".jpg")
mkdir -p "${folder}" && mv "${folder}".* "${folder}"
done
}
doWork "$#"
Example data directory: (before executing script)
$ ls data
Banner-A.jpg Banner-A.psd Banner-B.jpg Banner-B.psd Banner-C.jpg Banner-C.psd
Run script:
./script.sh ./data
data directory after script:
$ ls data
Banner-A Banner-B Banner-C
data directory subdirectories:
$ ls data/Banner-*
data/Banner-A:
Banner-A.jpg Banner-A.psd
data/Banner-B:
Banner-B.jpg Banner-B.psd
data/Banner-C:
Banner-C.jpg Banner-C.psd
I'd probably just use
for f in Banner*.jpg Banner*.psd; do
mkdir -p "${f%.???}/"
mv "$f" "${f%.???}/"
done
It will execute the mkdir -p for the *.psg files after the *.jpg has already created the folder, but covers the odd cases where there might be one of the files but not the other.

Create folders with filenames and move files into folder

I have a bunch of files that end with .EHZ and I am trying to create a folder for each of these files and then move them into the corresponding folders. Also the files have a Z attached to the name that I would like to remove. So ideally i would have, for example these files
AAAAZBBBBZ.EHZ
CCCCZDDDDZ.EHZ
EEEEZFFFFZ.EHZ
Turn into the folders
AAAABBBB
CCCCDDDD
EEEEFFFF
What I have written so far is
dir0=pwd
for file in `ls *.EHZ`
do
name=echo $file | head 10
mkdir -p $name
mv "$file" "$name"
done
P.S. I have found many answers in stackoverflow that were addressed to this issue but not on shell so I figured I would ask.
Could you please try following. I have used cp command for safer side in my code, you could remove it and put it as mv in there to actually move files to folders.
for file in *.EHZ
do
name="${file%.*}"
actual_directory_name="${name::-1}"
if [[ ! -d "$actual_directory_name" ]]
then
mkdir "$actual_directory_name"
fi
cp "$file" "$actual_directory_name"
if [[ -s "$actual_directory_name/$file" ]]
then
echo "$file is moved Successfully to directory name $actual_directory_name now.."
else
echo "Please check seems $file is NOT moved to directory $actual_directory_name."
fi
done

How to move files from subfolders to their parent directory (unix, terminal)

I have a folder structure like this:
A big parent folder named Photos. This folder contains 900+ subfolders named a_000, a_001, a_002 etc.
Each of those subfolders contain more subfolders, named dir_001, dir_002 etc. And each of those subfolders contain lots of pictures (with unique names).
I want to move all these pictures contained in the subdirectories of a_xxx inside a_xxx. (where xxx could be 001, 002 etc)
After looking in similar questions around, this is the closest solution I came up with:
for file in *; do
if [ -d $file ]; then
cd $file; mv * ./; cd ..;
fi
done
Another solution I got is doing a bash script:
#!/bin/bash
dir1="/path/to/photos/"
subs= `ls $dir1`
for i in $subs; do
mv $dir1/$i/*/* $dir1/$i/
done
Still, I'm missing something, can you help?
(Then it would be nice to discard the empty dir_yyy, but not much of a problem at the moment)
You could try the following bash script :
#!/bin/bash
#needed in case we have empty folders
shopt -s nullglob
#we must write the full path here (no ~ character)
target="/path/to/photos"
#we use a glob to list the folders. parsing the output of ls is baaaaaaaddd !!!!
#for every folder in our photo folder ...
for dir in "$target"/*/
do
#we list the subdirectories ...
for sub in "$dir"/*/
do
#and we move the content of the subdirectories to the parent
mv "$sub"/* "$dir"
#if you want to remove subdirectories once the copy is done, uncoment the next line
#rm -r "$sub"
done
done
Here is why you don't parse ls in bash
Make sure the directory where the files exist is correct (and complete) in the following script and try it:
#!/bin/bash
BigParentDir=Photos
for subdir in "$BigParentDir"/*/; do # Select the a_001, a_002 subdirs
for ssdir in "$subdir"/*/; do # Select dir_001, … sub-subdirs
for f in "$ssdir"/*; do # Select the files to move
if [[ -f $f ]]; do # if indeed are files
echo \
mv "$ssdir"/* "$subdir"/ # Move the files.
fi
done
done
done
No file will be moved, just printed. If you are sure the script does what you want, comment the echo line and run it "for real".
You can try this
#!/bin/bash
dir1="/path/to/photos/"
subs= `ls $dir1`
cp /dev/null /tmp/newscript.sh
for i in $subs; do
find $dir1/$i -type f -exec echo mv \'\{\}\' $dir1/$i \; >> /tmp/newscript.sh
done
then open /tmp/newscript.sh with an editor or less and see if looks like what you are trying to do.
if it does then execute it with sh -x /tmp/newscript.sh

Shell script to move files into another directory based on their name

I am new to Unix shell scripting. I have a small task of moving files into another directory based on their names.
I have a directory named Cars containing .csv files. I have to read the .csv file names, and move each file into another directory based on the filename, as follows:
BMW_c.csv must go into the BMW/c/ directory.
Mercedes_x.csv must go into the Mercedes/x/ directory.
I tried using for and if loop but couldn`t do it till sub directory.
I highly appreciate your help.
Something like this might work
for f in *.csv; do
DIR="$( echo ${f%.*} | tr '_' '/')"
mkdir -p "./$DIR"
mv "$f" "$DIR"
done
It will read all *.csv files, replace '_' by '/' in the file names (with .csv removed), create the directory and move the file. There will be errors if there are no csv files in the current directory.
I have done this and tried,it works.If any modifications or enhancements in the script you can post your answers..
cd /DIR/Cars/BMW
for f in *.csv
do
filename="${f##*/}"
echo ${filename}
if [[ "${f}" == *c* ]]
then
echo "moving files..."
mv "${f}" /BMW/c/
fi
done
cd /DIR/Cars/Mercedes
for f in *.csv
do
filename="${f##*/}"
echo ${filename}
if [[ "${f}" == *x* ]]
then
echo "moving files..."
mv "${f}" /Mercedes/x/
fi
done

Moving multiple files in different folder

I need make multiple folder having the name from file without extension with this command
for i in *.avi; do mkdir "${i%.*}"; done
I don't know how to mv the related file in the folder made...
Thanks for any help
Thanks. Let's say I want to do a general script to record on Textexpander which ask me for the file extension a sort of this :
echo "Type the suffix of the file follewe by enter:"
read ext
for i in *.ext
do
mkdir "${i%.ext}"
mv "$i" "${i%.ext}"
done
But this is not working.
Use the mv command:
for i in *.avi
do
mkdir "${i%.*}"
mv "$i" "${i%.*}"
done

Resources