Create folders with filenames and move files into folder - shell

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

Related

How can i create sub directories within a directory?

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.

Check if files exists in 3 different directories and move them one to another

I'm quite new in creating shell scripts.
I'm developing a shell script that will backup my files once a day only.
I need to check which *.war files are in three different folders (input folder, production folder, backup folder)
If the same files exists in the three directories, don't perform backup.
If it doesn't, it must move the files in folder 2 to folder 3.
This is what I've done so far.
===============================
TODAY=$(date +%d-%m-%Y)
INPUT=/home/bruno.ogasawara/entrada/
BACKUP=/home/bruno.ogasawara/backup/
PROD=/home/bruno.ogasawara/producao/
DIR1=$(ls $INPUT)
DIR2=$(ls $PROD)
DIR3=$(ls $BACKUP$TODAY)
for i in $DIR1; do
for j in $DIR2; do
for k in $DIR3; do
if [ $i == $j ] && [ $j == $k ]; then
exit 1; else
mv -f $PROD$j $BACKUP$TODAY
fi
done
done
done
mv -f $INPUT*.war $PROD
===============================
The verification is not working. Only thing working is the mv -f $INPUT*.war $PROD in the end.
Where am I missing something or doing something wrong?
Thanks in advance people.
What I understand is you want to sync those three folders.
In that case you should not modify the file names as we are using file names to compare them.Otherwise you should use md5 or sha checksums.But linux filesystem already has timestamps feature you don't have to attach date to filename.
In your code you used ls to list files ...but actually ls command lists files in column mode which is not comaptible with for loop in bash.
correct command is
find $DIR -maxdepth 1 -type f -exec basename {} \;
you want to sync the *.war files to all folders...then simply you can use this:
#!/bin/bash
DIR1=/home/bruno.ogasawara/entrada/
DIR2=/home/bruno.ogasawara/backup/
DIR3=/home/bruno.ogasawara/producao/
cp -n $DIR1/*.war $DIR2
cp -n $DIR1/*.war $DIR3
cp -n $DIR2/*.war $DIR1
cp -n $DIR2/*.war $DIR3
cp -n $DIR3/*.war $DIR1
cp -n $DIR3/*.war $DIR2
-n: will check if file already exists.it will not overwrite the existing file.

Shell Script to list files in a given directory and if they are files or directories

Currently learning some bash scripting and having an issue with a question involving listing all files in a given directory and stating if they are a file or directory. The issue I am having is that I only get either my current directory or if a specify a directory it will just say that it is a directory eg. /home/user/shell_scripts will return shell_scipts is a directory rather than the files contained within it.
This is what I have so far:
dir=$dir
for file in $dir; do
if [[ -d $file ]]; then
echo "$file is a directory"
if [[ -f $file ]]; then
echo "$file is a regular file"
fi
done
Your line:
for file in $dir; do
will expand $dir just to a single directory string. What you need to do is expand that to a list of files in the directory. You could do this using the following:
for file in "${dir}/"* ; do
This will expand the "${dir}/"* section into a name-only list of the current directory. As Biffen points out, this should guarantee that the file list wont end up with split partial file names in file if any of them contain whitespace.
If you want to recurse into the directories in dir then using find might be a better approach. Simply use:
for file in $( find ${dir} ); do
Note that while simple, this will not handle files or directories with spaces in them. Because of this, I would be tempted to drop the loop and generate the output in one go. This might be slightly different than what you want, but is likely to be easier to read and a lot more efficient, especially with large numbers of files. For example, To list all the directories:
find ${dir} -maxdepth 1 -type d
and to list the files:
find ${dir} -maxdepth 1 -type f
if you want to iterate into directories below, then remove the -maxdepth 1
This is a good use for globbing:
for file in "$dir/"*
do
[[ -d "$file" ]] && echo "$file is a directory"
[[ -f "$file" ]] && echo "$file is a regular file"
done
This will work even if files in $dir have special characters in their names, such as spaces, asterisks and even newlines.
Also note that variables should be quoted ("$file"). But * must not be quoted. And I removed dir=$dir since it doesn't do anything (except break when $dir contains special characters).
ls -F ~ | \
sed 's#.*/$#/& is a Directory#;t quit;s#.*#/& is a File#;:quit;s/[*/=>#|] / /'
The -F "classify" switch appends a "/" if a file is a directory. The sed code prints the desired message, then removes the suffix.
for file in $(ls $dir)
do
[ -f $file ] && echo "$file is File"
[ -d $file ] && echo "$file is Directory"
done
or replace the
$(ls $dir)
with
`ls $`
If you want to list files that also start with . use:
for file in "${dir}/"* "${dir}/"/.[!.]* "${dir}/"/..?* ; do

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