I need to write a script that will look for all files with the suffix ~ (eg file.txt ~) in current directory. If the script will find something, it should be copied to BACKUP directory.
If the BACKUP directory does not exist, the script should create it. If there is already a file (or other non-directory) named BACKUP, the script should report an error.
The problem is that on line if [ $x -eq BACKUP.* ];. Bash shows if [ $x -eq BACKUP.* ];
Appreciate any help
#!/bin/bash
if [ ! -d BACKUP ];
then
mkdir BACKUP;
fi
for x in *. *~ ; do
if [ $x -eq BACKUP.* ];
then
echo "Error, file BACKUP exist";
else
cp ./$x ./BACKUP;
fi
done
You mean something like that?
#!/bin/bash
BACKUP=./BACKUP
if [[ -e "$BACKUP" ]]; then
echo "$BACKUP already exists!" >&2
exit 1
fi
mkdir "$BACKUP"
find . -maxdepth 1 -type f -name "*~" -exec cp {} "$BACKUP" \;
Related
I created this script for check whether specific files exist or not in the given location. but when I run this its always showing
Failed - Flag_lms_device_info_20160628.txt do not exist
Failed - Flag_lms_weekly_usage_info_20160628 do not exist
but both files are existing.
PREFIX="/opt/data"
REPORT="/tmp/report.txt"
DATE=$( date -d "${dtd} -1 days" +'%Y%m%d' )
rm -f "$REPORT"
FILENAME="Flag_lms_device_info_${DATE}.txt"
FULLFN="$PREFIX/$FILENAME"
if [ -f "$FULLFN" ]; then
echo "OK - $FILENAME exists" >> $REPORT
else
echo "Failed - $FILENAME do not exist" >> $REPORT
fi
FILENAME="Flag_lms_weekly_usage_info_${DATE}.txt"
FULLFN="$PREFIX/$FILENAME"
if [ -f "$FULLFN" ]; then
echo "OK - $FILENAME exists" >> $REPORT
else
echo "Failed - $FILENAME do not exist" >> $REPORT
fi
First of all, you have strange output in your question: your second line of output lacks a .txt extension. This might be an accident but if it's not it's worth investigating.
Assuming your date command is working correctly (I don't know that particular command), I would reduce your use of variables. In addition, I would use the -e test operator instead of -f because it's more inclusive. (If you haven't put data in the files yet, -f could return an error even if the file exists.) :
REPORT="/tmp/report.txt"
DATE=$( date -d "${dtd} -1 days" +'%Y%m%d' )
echo "" > "$REPORT" # Wipes file instead of completely removing it
filename="/opt/data/Flag_lms_device_info_$DATE.txt"
if [ -e "$filename" ]; then
echo "OK - Flag_lms_device_info_$DATE.txt exists" >> $REPORT
else
echo "Failed - Flag_lms_device_info_$DATE.txt doesn't exist" >> $REPORT
fi
filename="/opt/data/Flag_lms_weekly_usage_info_$DATE.txt"
if [ -e "$filename" ]; then
echo "OK - Flag_lms_weekly_usage_info_$DATE.txt exists" >> $REPORT
else
echo "Failed - Flag_lms_weekly_usage_info_$DATE.txt doesn't exist" >> $REPORT
fi
if [ -f "find "$FULLFN" -type f -name "$FILENAME"" ];then
Here you check for existance of a strange file named find... Use backquotes
if [ -f `find "$FULLFN" -type f -name "$FILENAME"` ];then
or, in bash,
if [ -f $(find "$FULLFN" -type f -name "$FILENAME") ];then
to get the command's output as a string.
Furthermore, your find invocation does not look promising. If you need to find a file named Flag_lms_device and so forth somewhere under /opt/data/, use find "$PREFIX" -type f -name "$FILENAME". If you know for sure that /opt/data is the exact location, then use
if [ -f "$FULLFN" ]
and you don't need to find the file.
#!/bin/bash
#sh j
find . -name "*first*" && echo "file found" || echo "file not found"
read -p "Run command $foo? [yn]" answer
case "$answer" in
y*) find . -type f -exec rename 's/(.*)\/(.*)first(.*)/$1\/beginning_$2changed$3/' {} + ;;
n*) echo "not renamed" ;;
esac
fi
I want the script to loop through folder and subfolders and find files that contain certain string and then have an option to rename the file or let it be(That is the y/n option) after selection the script should continue finding.
Also i have a problem that says "syntax error unexpected token 'fi' "
Try this:
#bin/bash
handle_file(){
local file=$0
local pattern=some_pattern
if [[ $(grep -c ${pattern} ${file}) -gt 0 ]];
then
......................................
do anything you want with your ${file}
......................................
fi
}
export -f handle_file
find . -type f -exec bash -c 'handle_file "$#"' {} \;
handle_file is a function that will be invoked as handle_function <filename>, so the <filename> is available as $0 inside the function.
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
I keep getting these errors running my script and i just cannot work it out...
the error that keeps coming up is;
rm: cannot remove ~/my-documents/article:': Is a directory. The directory its referring to is $2...here is my script.
#! /bin/sh
SRC=$1
DES=$2
if [ $# -ne 2 ]; then
echo "1. Please enter the source directory"
echo "2. Please enter the destination directory"
echo "thankyou"
exit
fi
if [ ! -d $1 ]; then
echo "$1 is not a directory please enter a valid directory"
echo "thankyou"
exit
fi
#gives the user a error warning the source directory is invalid
if [ -d $2 ]; then
echo "output directory exists"
else
echo "Output directory does not exist, creating directory"
mkdir $2
fi
#creates the destination directory if one doesn't exist
IFILE=$GETFILES;
FINDFILE=$FINDFILE;
find $1 -name "*.doc" > FINDFILE
find $1 -name "*.pdf" > FINDFILE
find $1 -name "*.PDF" > FINDFILE
#finds doc, pdf & PDF files and sends data to findfile.
while read -r line;
do
cp $line $2
done < FINDFILE
#files read and copied to destination directory
IFILE=$2/$GETFILES;
ls -R $1 | egrep -i ".doc | .pdf" > IFILE;
LCOUNT=0
DIFFCOUNT=0
FOUND=0
ARCHIVE=1
BASE="${line%.*}"
EXTENSION="${line##*.}"
COUNT=$COUNT;
ls $2 | grep ${line%%.*} \; | wc -l
if [[ $COUNT -eq 0 ]];
then
cp $1/$line $2;
else
echo "there is already a file in the output so need to compare"
COMP=$2/$line
fi
while [[ $FOUND -eq 0 ]] && [[ $LCOUNT -lt $COUNT ]];
do
echo "diffcount is $DIFFCOUNT"
###compares the file from the input directory to the file in
###the output directory
if [ $DIFFCOUNT -eq 0 ];
then
echo "file has already been archived no action required"
FOUND=$FOUND [ $FOUND+1 ]
else
LCOUNT=$LCOUNT [ $LCOUNT+1 ]
COMP="OUT"/"$BASE"_"$LCOUNT"."$EXTENSION"
echo "line count for next compare is $LCOUNT"
echo "get the next file to compare"
echo "the comparison file is now $COMP"
fi
if [ $LCOUNT -ne $COUNT ]; then
ARCHIVE=$ [ $ARCHIVE+1 ]
else
ARCHIVE=0
fi
if [ $ARCHIVE -eq 0 ];
then
NEWOUT="OUT"/"$BASE"_"$LCOUNT"."$EXTENSION";
echo "newfile name is $NEWOUT"
cp $1/$LINE $NEWOUT
fi
done < $IFILE
rm $IFILE
OFILE=$2/DOCFILES;
ls $2 | grep ".doc" > $OFILE;
while read -r line;
do
BASE=${line%.*}
EXTENSION=${line##*.}
NEWEXTENSION=".pdf"
SEARCHFILE=$BASE$NEWEXTENSION
find $2 -name "$SEARCHFILE" -exec {} \;
done < $OFILE
rm $OFILE
### this will then remove any duplicate files so only
### individual .doc .pdf files will exist
a plain call to rm can only remove files, not directories.
$ touch /tmp/myfile
$ rm /tmp/myfile
$ mkdir /tmp/mydir
$ rm /tmp/mydir
rm: cannot remove ‘/tmp/mydir/’: Is a directory
You can remove directories by specifying the -d (to delete empty directories) or the -r (to delete directories and content recursively) flag:
$ mkdir /tmp/mydir
$ rm -r /tmp/mydir
$
this is well described in man rm.
apart from that, you seem to ignore quoting:
$ rm $OFILE
might break badly if the value of OFILE contains spaces, use quotes instead:
$ rm "${OFILE}"
and never parse the output of ls:
ls $2 | grep ".doc" > $OFILE
(e.g. if your "$2" is actually "/home/foo/my.doc.files/" it will put all files in this directory into $OFILE).
and then you iterate over the contents of this file?
instead, just use loop with file-globbing:
for o in "${2}"/*.doc
do
## loop code in here
done
or just do the filtering with find (and don't forget to call an executable with -exex):
find "$2" -name "$SEARCHFILE" -mindepth 1 -maxdepth 1 -type f -exec convertfile \{\} \;
I'm trying to work on a script that will crawl my Plex media folder, find any header ".r00" files, extract them in their own directory, and trash the archive zips after it's done. I have two options I've been playing around with. Combined they do what I want, but I would like to have it all in one nice little script.
Option 1:
This script opens the "LinRAR" GUI, makes me navigate to a specific directory, finds and extracts any .r00 file in that directory, and successfully deleted all archive zips.
while true; do
if dir=$(zenity --title="LinRAR by dExIT" --file-selection --directory); then
if [[ ! -d $dir ]]; then
echo "$dir: Wrong Directory" >&2
else
( cd "$dir" && for f in *.r00; do [[ -f $f ]] || continue; rar e "$f" && rm "${f%00}"[0-9][0-9]; done )
fi
else
echo "$bold Selection cancelled $bold_off" >&2
exit 1
fi
zenity --title="What else...?" --question --text="More work to be done?" || break
done
Option 2:
This script cd's to my Plex folder, recursively finds any .r00 files, extracts to my /home/user folder, and does not remove the archive zips.
(cd '/home/user/Plex');
while [ "`find . -type f -name '*.r00' | wc -l`" -gt 0 ];
do find -type f -name "*.r00" -exec rar e -- '{}' \; -exec rm -- '{}' \;;
done
I would like to have something that takes the first working script, and applies the recursive find to all folders inside of /Plex instead of only letting me navigate to one folder at a time through the "LinRAR" GUI.
No need to use cd. find takes a starting directory.
It's that dot (.) you passed to it.
Also added another (more sane) alternative for the find & loop:
#!/bin/bash
while true; do
if dir=$(zenity --title="LinRAR by dExIT" --file-selection --directory); then
if [[ ! -d $dir ]]; then
echo "$dir: Wrong Directory" >&2
else
# Alternative 1 - a little more comfortable
files="$(find "${dir}" -type f -name '*.r00')"
for file in ${files}; do
rar e "${file}" && rm "${file}"
done
# Alternative 2 - based on your original code
while [ "`find "${dir}" -type f -name '*.r00' | wc -l`" -gt 0 ]; do
find "${dir}" -type f -name "*.r00" -exec rar e -- '{}' \; -exec rm -- '{}' \;;
done
fi
else
echo "$bold Selection cancelled $bold_off" >&2
exit 1
fi
zenity --title="What else...?" --question --text="More work to be done?" || break
done
According to the comments, I ran a small example of this code and it works perfectly fine:
#!/bin/bash
if dir=$(zenity --title="LinRAR by dExIT" --file-selection --directory); then
if [[ ! -d $dir ]]; then
echo "$dir: Wrong directory" >&2
else
find $dir -type f
fi
else
echo "cancelled"
fi
A directory is successfully picked and all its files are printed. If I chose to cancel in zenity, then it prints 'cancelled'.
I need to make a shell script that has 2 arguments, each one a valid directory. The script makes a new directory in the first directory specified by the first argument with the same name as the second one and copies the content(both subdirectories and files) of the second one in the newly created directory. But it only copies the files with .txt extension.
This is what I got so far:
#!/bin/bash
if [ ! $# -eq 2 ]
then echo usage: file.sh directory1 directory2
exit 1
fi
if [ ! -d $1 ]
then echo $1 is not a directory \!
exit 1
fi
if [ ! -d $2 ]
then echo $2 is not a directory \!
exit 1
fi
Leaving debugging to the student:
die () { echo >&2 "$*"; echo "Usage...."; exit 1; }
from="$1";
to="$2";
[ ."$from" = . ] && die "from dir name missing";
[ ."$to" = . ] && die "to dir name missing";
[ -d "$from" ] || die "from dir $from not a directory";
[ -d "$to" ] || die "to dir $to not a directory";
target="$to/$(basname "$from")"; #final target dir name, if I understand you correctly.
find "$from" -name '*.txt' -maxdepth=1 | cpio -pd "$to" ||
# (cd "$from" && find * -name '*.txt' -maxdepth=1 | cpio -o...) | ( cd "$to" && cpio -i...) ||
die "cpio failed"
Beware that cpio has many options and you should review them before using it.
The commented out technique allows you to more freely move to alternate target directories, which I do not think you need here.
Avoid grief: always quote file names.
Simply append this at the and of your script:
cp -dR $2 $1
You may have a better chance using rsync
For example:
rsync -avz /dir1/ /dir2
Depending on your preferences about conservation of file properties, many one-liner alternatives exist around cp, tar or rsync. Filtering can be obtained using the findcommand.