ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
I am writing a bash script with puppywary 5.3 distro. Basically, the script has to find certain files with extensions and move them to another directory.
Sounds easy, however, if there are files with the same name but different extensions only the one with .docx has to be copied. That's where the fun starts. When I try to do copy command with multiple files I get this:
cp: cannot stat `dir/filename\ndir/filename': no such file or directory
I know that \n is a newline character however I have no idea how does it get in between files when copying and whether its because flaws in code or because I am using distro. It concatenates both paths of files and prevents from copying.
Also, all the files I am copying are empty, using for test.
Thanks guys!
Code:
#!/bin/sh
src=$1
dst=$2
fdoc=$(find "$src" -type f -name "*.doc" 2>/dev/null)
fdocx=$(find "$src" -type f -name "*.docx" 2>/dev/null)
fpdf=$(find "$src" -type f -name "*.pdf" 2>/dev/null)
if [ ! -d "$src" ]; then
echo "The path: $src does not exist. Please check the path"
exit=1
fi
[ ! -d "$dst" ]
mkdir -p "$dst"
for i in "$src"; do
if [[ "$(basename "$fdoc" .doc)" == "$(basename "$fdocx" .docx)" ]]
cp "$fdocx" "$dst"
fi
done
Please note: it is just the part of the code to compare two filenames and copy the .docx version.
I would guess there is a bug in your script - of course it is a guess since you haven't posted the script that is causing the error. Should you decide to post the code please use [code][/code] tags.
fdoc=$(find "$src" -type f -name "*.doc" 2>/dev/null)
fdocx=$(find "$src" -type f -name "*.docx" 2>/dev/null)
fpdf=$(find "$src" -type f -name "*.pdf" 2>/dev/null)
This seems to break once there are multiple .doc, .docx or .pdf files in $src. Your script assumes that if there is any doc or docx file, there is exactly one.
Code:
[ ! -d "$dst" ]
This is pointless (unless you add set -e somewhere at the beginning).
Code:
for i in "$src"; do
This is equivalent to i=$src.
Code:
if [[ "$(basename "$fdoc" .doc)" == "$(basename "$fdocx" .docx)" ]]
Youre claiming to use /bin/sh so do so:
Code:
if [ "$(basename "$fdoc" .doc)" = "$(basename "$fdocx" .docx)" ]
fdoc=$(find "$src" -type f -name "*.doc" 2>/dev/null)
fdocx=$(find "$src" -type f -name "*.docx" 2>/dev/null)
fpdf=$(find "$src" -type f -name "*.pdf" 2>/dev/null)
This seems to break once there are multiple .doc, .docx or .pdf files in $src. Your script assumes that if there is any doc or docx file, there is exactly one.
Hey mina86 and thank you for your reply.
Any ideas how to fix my code ? I am relatively new to bash scripting.
However, when I use find command it gives me all files with .doc .docx or .pdf extensions.
I usually just implement find in shell if I need to go through all files (with given extension) in a given directory and all its subdirectories. If you care about bash only, you can use extended globs like **/*.docx.
Not sure I understand the problem. If the goal is to find all *.docx files and copy them to another directory then I do not understand the significance if there are also *.doc or *.pdf files of the same name or the necessity to compare file names.
Not sure I understand the problem. If the goal is to find all *.docx files and copy them to another directory then I do not understand the significance if there are also *.doc or *.pdf files of the same name or the necessity to compare file names.
Homework assignment?
Hey MichaelK and thanks for joining us.
The problem is to find all .doc, .docx and .pdf files and copy them to a directory. However, if names of files with .doc and .docx are the same then only .docx should be copied.
Well the first thing that stood out to me was this:
Code:
if [ ! -d "$src" ]; then
echo "The path: $src does not exist. Please check the path"
exit=1
fi
You call this 'after' having already attempting to use $src in your find commands ... bit pointless after the fact.
Then as the question is homework, my suggestion would be:
1. Use find with -exec option to copy pdf and docx files to location
2. Pump find of doc files into a loop (while) and test the file name does not exist in the destination and then copy if not there
Note: Your current issue is with find as the default output from the find command is to place each found item on a separate line using newline. You could look into the -print option of find
find . -iname '*.doc' -print | while read -r FILE; do
Which of course breaks if there is a file with newline in its name, which is the reason I suggest implementing find in bash.
Quote:
Originally Posted by mrquartz
The problem is to find all .doc, .docx and .pdf files and copy them to a directory. However, if names of files with .doc and .docx are the same then only .docx should be copied.
What if there is file with the same name in two different subdirectories of $src?
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.