Create new Directories with Bash Script - bash

I'd like to create a script to run every hour (with crontab) to make a folder with the name of any file with the correct extension (minus the extension) and move that file into it. So the end result would be the script would execute, find every .mp4 file in /Directory, create a folder for each of them with the same name as the file (minus extension) in /Other/Directory, and move the file into the matching folder. I can understand not wanting to write something for someone for free, but if you could point me in the right direction, I would really appreciate it.
EDIT: Thanks to #Barmar for the help!
#!/bin/bash
cd "/home/kali/Videos"
for FILE in *;do
bn=$(basename $FILE .mp4)
mkdir /home/kali/Videos/$bn;done
mv $bn.mp4 /home/kali/Videos/$bn

The script you would be looking for is as follows:
#!/bin/bash
REPOSITORY="/home/kali/Videos"
cd "${REPOSITORY}"
### This approach is best for handling filenames that might have spaces or scpecial characters.
ls |
while [ true ]
do
read FILE
if [ -z "${FILE}" ] ; then break ; fi
if [ -f "${FILE}" ]
then
bn=`basename "${FILE}" ".mp4" `
mkdir "${REPOSITORY}/$bn"
mv "${FILE}" "${REPOSITORY}/$bn"
( cd "${REPOSITORY}/$bn" ; extract_images "./${FILE}" )
fi
done

Related

Is there a way I can take user input and make it into a file?

I am not able to find a way to make bash create a file with the same name as the file the user dragged into the terminal.
read -p 'file: ' file
if [ "$file" -eq "" ]; then
cd desktop
mkdir
fi
I am trying to make this part of the script take the name of the file they dragged in so for example /Users/admin/Desktop/test.app cd into it copy the "contents" file make another folder with the same name so test.app for this example and then paste the contents file into that folder and delete the old file.
From your .app example, I assume you are using MacOS. Therefore you will need to test this script yourself since I don't have MacOS, but I think it should be doing what you want. Execute it as bash script.sh and it will give you your desired directory test.app/contents in the current working directory.
#! /bin/bash
read -rp 'file: ' file
if [ -e "$file" ]; then
if [ -e "$file"/contents ]; then
base=$(basename "$file")
mkdir "$base"
cp -R "$file"/contents "$base"
rm -rf "$file"
else
echo "The specified file $file has no directory 'contents'."
fi
else
echo "The specified file $file does not exist."
fi

Bash get list of zip files in dir and perform some operations on each of them

I have a bash script, which goes through list of directories and if some directory contains zip files it bind zip file name into variable and perform some actions over it and then goes to another in this dir. Unfortunately, it works when there is one zip file per directory. If more - it gives error "Binary operator expected"
Script:
if [ -e $currdir/*.zip ]; then
for file in $currdir/*.zip; do
echo the zip is "${file##*/}"
done
Please help me to rework script accordingly.
If you need exactly check then you can use:
if [[ -n $(echo "$currdir"/*.zip) ]]; then
for f in "$currdir"/*.zip; do
echo "Processing $f file..";
done
fi
But I'd prefer just looping over files that contain *.zip extension:
for f in "$currdir"/*.zip; do
echo "Processing $f file..";
done
Use
for file in "$currdir"/*.zip; do
[ -e "$file" ] || continue
echo the zip is "${file##*/}"
done
As pointed out in the comments the glob will happen in the shell, then [ is called with the output, i.e:
[ -e * ]
will become:
[ -e Desktop Documents Downloads ... ]
Therefore trying to expand and checking in the for iteration will work.
Please see: http://mywiki.wooledge.org/WordSplitting and http://wiki.bash-hackers.org/syntax/expansion/globs
I think the case construct is too often overlooked.
case *.jpg in *.jpg ) echo found files ;; * ) echo no files found ;; esac
produces the correct message in my dir with 1000s+ jpgs ;-)
Change both references from jpg to zip and see if it works for you.
IHTH

Shell Script to copy all files in a directory to a specified folder

I'm new in shell script and I am trying to figure out a way to write a script that copies all the files in the current directory to a directory specified from a .txt file and if there are matching names, it adds the current date in the form of FileName_YYYYMMDDmmss to the name of the file being copied to prevent overwritting.
Can someone help me out?
I saw thinking something along the lines of
#!/bin/bash
source=$pwd #I dont know wheter this actually makes sense I just want to
#say that my source directory is the one that I am in right now
destination=$1 #As I said I want to read the destination off of the .txt file
for i in $source #I just pseudo coded this part because I didn't figure it out.
do
if(file name exists)
then
copy by changing name
else
copy
fi
done
the problem is I have no idea how to check whether the name exist and copy and rename at the same time.
Thanks
How about this? I am supposing that the target directory is in the
file new_dir.txt.
#!/bin/bash
new_dir=$(cat new_dir.txt)
now=$(date +"%Y%m%d%M%S")
if [ ! -d $new_dir ]; then
echo "$new_dir doesn't exist" >&2
exit 1
fi
ls | while read ls_entry
do
if [ ! -f $ls_entry ]; then
continue
fi
if [ -f $new_dir/$ls_entry ]; then
cp $ls_entry $new_dir/$ls_entry\_$now
else
cp $ls_entry $new_dir/$ls_entry
fi
done
I guess this what you are looking for :
#!/bin/bash
dir=$(cat a.txt)
for i in $(ls -l|grep -v "^[dt]"|awk '{print $9}')
do
cp $i $dir/$i"_"$(date +%Y%m%d%H%M%S)
done
I assumed that a.txt contains only the name of the destination directory. If there are other entries, you should add some filter to the first statement(using grep or awk).
NB: I used full time stamp(YYYYMMDDHHmmss) instead of your YYYYMMDDmmss as it doesn't seem logical.

Simple Bash Script File Copy

I am having trouble with a simple grading script I am writing. I have a directory called HW5 containing a folder for each student in the class. From my current directory, which contains the HW5 folder, I would like to copy all files starting with the word mondial, to each of the students' folders. My script runs but does not copy any of the files over. Any suggestions?
#!/bin/bash
for file in ./HW5; do
if [ -d $file ]; then
cp ./mondial.* ./$file;
fi
done
Thanks,
The first loop was executing only once, with file equal ./HW5. Add the star to actually select the files or directories inside it.
#!/bin/bash
for file in ./HW5/*; do
if [ -d "$file" ]; then
cp ./mondial.* ./"$file"
fi
done
As suggested by Mark Reed, this can be simplified:
for file in ./HW5/*/; do
cp ./mondial.* ./"$file"
done

Passing Variables through Nested Shell Scripts

I have a simple loop in my Shell Script and want to be able to run another loop for each file in the directory...right now I am just asking for it to echo each file but I do want to do more with each file, but want to figure this out first...
for dir in "$#/"*
do
folder=$(basename "$dir")
path="/Users/wme/Desktop/test3/"
if [ ! -d "$path$folder" ]; then
mkdir "$path$folder"
mkdir "$path$folder/mp4"
mkdir "$path$folder/mov"
mkdir "$path$folder/ogg"
mkdir "$path$folder/webm"
mkdir "$path$folder/img"
fi
for file in "$dir/"*
echo $file
done
done
So essentially it is finding all the directories creating a folder structure for those folders, and now I need to go and process the movies in each of those folders...but I get an error when I try to do the second nested loop, what am I doing wrong?
Also it should be noted I am running this in Automator so it doesn't really give me an error, just says action failed
You will also have an issue with your first for loop. "$#/"* will expand to $1 $2 ... $n/*, not $1/* $2/* ... $n/*. You'll need
path="/Users/wme/Desktop/test3"
for dir in "$#"; do
for subdir in "$dir/"*; do
folder=$(basename "$subdir")
if [ ! -d "$path/$folder" ]; then
for ftype in mp4 mov ogg webm img; do
mkdir -p "$path/$folder/$ftype"
done
fi
for file in "$subdir/"*
echo $file
done
done

Resources