Issue creating a folder then moving files into it within the same script - linux

I'm having problems moving files into a folder after I create it in a shell script.
My script looks like:
#!/bin/bash
echo -e "Processing\033[36m" $1 "\033[0mwith the German script";
if [ ! -d ${1%.dat} ]; then
echo -e "making directory\033[33m" ${1%.dat} "\033[0msince it didn't exist...";
mkdir ${1%.dat};
fi
...processing occurs here... (irrelevant to issue)
if [ -d ${1%.dat} ]; then
mv useragents_$1 /${1%.dat}/useragents_$1;
mv summary_$1 /${1%.dat}/summary_$1;
more /${1%.dat}/useragents_$1;
else
echo -e "\033[31mERROR: cannot move files to folder.\033[0m";
fi
As you can see I create the folder if it doesn't exist in the top section and then if it exists I move the files into that folder in the bottom section, the problem is that it doesn't create the folder in time to move the files in (I'm assuming) so when it reaches the lower code, I only get the ERROR.
I tried using, sleep 5, but it only slows down the script and has no effect on the ERROR.
I would really appreciate some advice.
Errors below:
mv: cannot move `useragents_100_stns2_stns6.dat' to `/100_stns2_stns6/useragents_100_stns2_stns6.dat': No such file or directory
mv: cannot move `summary_100_stns2_stns6.dat' to `/100_stns2_stns6/summary_100_stns2_stns6.dat': No such file or directory
/100_stns2_stns6/useragents_100_stns2_stns6.dat: No such file or directory

Pass 1
Your check:
if [ ! -d ${1%.dat} ]; then
should be:
if [ -d ${1%.dat} ]; then
You created the directory; if it is a directory, move stuff into it.
Typo in question
Pass 2
You create:
mkdir ${1%.dat}
You try to move files:
mv useragents_$1 /${1%.dat}/useragents_$1;
Note the leading slash in the move compared to the create. Make those consistent.

Are you sure of this part ? It uses a root directory.
/${1%.dat}/summary_$1;
You probably want to do this instead:
${1%.dat}/summary_$1;
It allows you to move the file into the directory IN your current directory.

Related

Shell script to copy one file at a time in a cron job

I have some csv files in location A like this
abc1.csv,
abc2.csv,
abc3.csv
I have a cron job which runs every 30 mins and in each execution I want to copy only 1 file(which shouldn't be repeated) and placed it in location B
I had though of 2 ways of doing this
1)I will pick the first file in the list of files and copy it to location B and will delete it once copied.Problem with this is I am not sure when the file will get copied completely and if i delete before its completed copied it can be an issue
2)I will have a temp folder.So i will copy the file from location A to location B and also keep it in temp location.In next iteration, when I pick the file from list of files I will compare its existence in the temp file location.If it exists I will move to next file .I think this will be more time consuming etc.
Please suggest if there is any other better way
you can use this bash script for your use case:
source="/path/to/.csv/directory"
dest="/path/to/destination/directory"
cd $source
for file in *.csv
do
if [ ! -f $dest/"$file" ]
then
cp -v $file $dest
break
fi
done
You can ensure you move the already copied file with:
cp abc1.csv destination/ && mv abc1.csv.done
(here you can make your logic to find only *.csv files, and not take into account *.done files.. that have been already processed by your script... or use any suffix you want..
if the cp does not succeed, nothing after that will get executed, so the file will not be moved.
You can also replace mv with rm to delete it:
cp abc1.csv destination/ && rm -f abc1.csv
Further more, you can add to the above commands error messages in case you want to be informed if the cp failed:
cp abc1.csv destination/ && mv abc1.csv.done || echo "copy of file abc1.csv failed"
And get informed via CRON/email output
Finally I took some idea from both the opted solution.Here is the final script
source="/path/to/.csv/directory"
dest="/path/to/destination/directory"
cd $source
for file in *.csv
do
if [ ! -f $dest/"$file" ]
then
cp -v $file $dest || echo "copy of file $file failed"
rm -f $file
break
fi
done

Custom command in linux to move files

I'm trying to create a command that allows me move a file to another directory. For example when I enter "move file1" in the command line, it should move the file "file1" to another directory. I know it can simply done as mv file1 /path/to/destination, But I want to create a new command. I'm kind of new Linux user, please help me.
This is what I tried:
Created an alias for move='/home/bin/move.sh'
So, now when I type move in the command line, it goes and execute move.sh script
Started writing a shell script move.sh as :
#!/bin/bash
mv "$2" "/path/to/destination"
I'm not knowing how to proceed. The whole process might be wrong too. Please help me solve this.
Thanks in advance
Create a function:
move () { mv -t /path/to/destination "$#" ;}
put it in ~/.bashrc to make it permanent.
Now run it as :
move /source /files
From here you can read on how to select arguments.
From here you can read more on how to check for number of arguments.
move.sh
#!/bin/bash
if (( $# < 2 )); then
# TODO: print usage
exit 1
fi
mv "$1" "$2"
Then you will need to make it executable.
chmod u+x move.sh
You can remove the .sh part. It wont change anything.
mv move.sh move
And then you should be able to call the file
move asd /home/
Just make sure that the alias calls the correct file.
If you want to make life easier delete the alias and place the file in the /bin/ directory
cp move /bin/
Good luck.

Having trouble implementing cp -u in shell script

For a school project, I have a shell script that is supposed to copy the files in two directories (without looking at subdirectories) into a third directory. I'm testing out the -u command so that if two files have the same name, only the newer one will get copied over (that's also a spec). My shell script looks like this (excluding #! and error checking):
cd $1 #first directory
for file in `ls`; do
if [ -f $file ]; then
cp "$file" ../$3 # $3 is the third directory
fi
done
cd ../$2
for file in `ls`; do
if [ -f $file ]; then
cp -u "$file" ../$3
fi
done
My current shell script will copy files that don't exist in directory 3 already, and it won't overwrite a newer file with an older file with the same name. However, my shell script doesn't overwrite an older file with a newer file of the same name in directory 3. I don't think there's anything wrong with the -u command. Can you help find the bug in my code? Thanks!
You are missing the -u option in the first loop:
cp "$file" ../$3 # $3 is the third directory
should instead read:
cp-u"$file" ../$3 # $3 is the third directory

Checking wether a directory exist in the home directory

Trying to check wether a directory exist in the the home directory
if [ ! -d "$HOME/Smart_Cycle" ]; then
mkdir Smart_Cycle $DIRPATH
echo "Creating DIrecroty""
fi
Trying to check wether the Smart_Cycle directory exist in the home directory, and if it does not exist it will create the directory. Not sure what is going on or if I am on the right track.
When running the script I have these two error that I have never seen before
./smartcycle: line 4: unexpected EOF while looking for matching `"'
./smartcycle: line 6: syntax error: unexpected end of file
EOF is because you have double "" in
"Creating DIrecroty""
As Etan suggested, a better way is to use
mkdir -p "$HOME/Smart_Cycle"
-p will make sure that all directories in the specified path exist and if not, they will be created.
You had an extra quotation mark on
echo "Creating DIrecroty""
Try this
if [ ! -d "$HOME/Smart_Cycle" ]; then
mkdir "$HOME/Smart_Cycle"
echo "Creating DIrecroty"
fi
You can create more than one directory at once
mkdir A B C
In your case, $DIRPATH will be evaluated and a second directory created pointing to the value contained in $DIRPATH

Bash: move file/directory and create a link of it

I am trying to make a bash script that moves a file or directory from source directory to destination directory and puts a symlink to it into source directory.
So, <source_path> can be a file or directory, <destination_dir_path> is the directory where I want the original moved to.
Sample usage:
$ mvln /source_dir/file.txt /destination_dir/
OR
$ mvln /source_dir/dir_I_want_to_move/ /destination_dir/
This is what I have managed to put together, but it does not work properly.
It works only if source is a directory, otherwise mv returns an error:
mv: unable to rename `/source_dir/some_file.txt': Not a directory
And the directory is not moved into destination_directory but only its contents are moved.
#!/bin/bash
SCRIPT_NAME='mvln'
USAGE_STRING='usage: '$SCRIPT_NAME' <source_path> <destination_dir_path>'
# Show usage and exit with status
show_usage_and_exit () {
echo $USAGE_STRING
exit 1
}
# ERROR file does not exist
no_file () {
echo $SCRIPT_NAME': '$1': No such file or directory'
exit 2
}
# Check syntax
if [ $# -ne 2 ]; then
show_usage_and_exit
fi
# Check file existence
if [ ! -e "$1" ]; then
no_file $1
fi
# Get paths
source_path=$1
destination_path=$2
# Check that destination ends with a slash
[[ $destination_path != */ ]] && destination_path="$destination_path"/
# Move source
mv "$source_path" "$destination_path"
# Get original path
original_path=$destination_path$(basename $source_path)
# Create symlink in source dir
ln -s "$original_path" "${source_path%/}"
Can some one please help?
The problem is that $destination_path refers to a directory that doesn't exist. Something like this:
mv /path/to/file.txt /path/to/non/existent/directory/
returns an error, and
mv /path/to/directory/ /path/to/non/existent/directory/
will rename /path/to/directory/ to /path/to/non/existent/directory/ (provided that /path/to/non/existent/ is an existent directory, just without a subfolder named directory).
If you are expecting that $destination_path doesn't already exist, then you can add a mkdir command:
mkdir "$destination_path"
mv "$source_path" "$destination_path"
if you're expecting that it might not exist, then you can add it conditionally:
[[ -d "$destination_path" ]] || mkdir "$destination_path"
mv "$source_path" "$destination_path"
and if you're expecting that it does exist, then you have some debugging to do!
(By the way, depending on your exact situation, you might find mkdir -p to be helpful. It recursively creates a directory and all necessary parent directories, and it doesn't mind if the directory already exists.)

Resources