LinuxQuestions.org
Share your knowledge at the LQ Wiki.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Newbie
User Name
Password
Linux - Newbie This Linux forum is for members that are new to Linux.
Just starting out and have a question? If it is not in the man pages or the how-to's this is the place!

Notices


Reply
  Search this Thread
Old 01-26-2011, 03:46 PM   #1
newbash
LQ Newbie
 
Registered: Jan 2011
Posts: 2

Rep: Reputation: 0
Simple bash question - replacing single quotes in filenames with another character


Hopefully easy !

Can anyone offer a code snippet to recursively go through directories and replace any single or double quotes quotes found in a filename with another character (e.g. "_").

My directory structure looks like :-

Parent
|--------DIR1
| |-----File1
| |-----File2
|
|--------DIR2
| |-----File3
| |-----File4

etc

If any of the filenames contain a single quote or double quote, then replace it with an underscore.

Thanks in advance !
 
Old 01-26-2011, 04:15 PM   #2
kbp
Senior Member
 
Registered: Aug 2009
Posts: 3,790

Rep: Reputation: 653Reputation: 653Reputation: 653Reputation: 653Reputation: 653Reputation: 653
Give this a go:

Code:
#!/bin/bash

if [[ $# -ne 1 ]]
then
        echo "Usage: $0 <dirname>"
        exit 1
fi

for file in $(find $1 -type f)
do
        echo "Testing $file"
        if [[ $(echo "$(basename $file)" | grep -q "\'") -eq 0 ]]
        then
                dirname=$(dirname $file)
                newfile=$(echo $(basename $file) | tr "'" "_")
                mv $file $dirname/$newfile
                echo "Changed $file to $newfile"
        fi
done
Sorry, just noticed you wanted double quotes as well, are you ok to modify the script above ?

Last edited by kbp; 01-26-2011 at 04:20 PM.
 
Old 01-26-2011, 05:59 PM   #3
grail
LQ Guru
 
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 10,007

Rep: Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191
As we already have unusual characters like quotes in file names, if i was a betting man I would say there are spaces as well which will word split if
using a for loop. So perhaps try something like:
Code:
#!/bin/bash

while read -r F_PATH
do
    FILE=${F_PATH##*/}
    mv $F_PATH ${F_PATH%/*}/${FILE//[\'\"]/_}
done< <(find $1 -type f -iname "*['\"]*")
 
Old 01-26-2011, 07:56 PM   #4
crts
Senior Member
 
Registered: Jan 2010
Posts: 2,020

Rep: Reputation: 757Reputation: 757Reputation: 757Reputation: 757Reputation: 757Reputation: 757Reputation: 757
Hi,

here is a single find that will do it
Code:
find "/path/to/dir/" -type f -iname "*['\"]*" -exec /bin/bash -c 'echo mv -n "${1}" "${1//["'\''"\"]/_}" ' {} {} \;
If the results look alright to you then remove the 'echo' to make the changes actually happen.
The '-n' option after the 'mv' command is there to make sure that no file is overwritten in case you have files like
file'with'quotes
file"with"quotes

In this case handling the renaming process will be a bit more complex. But at this point I assume that the target-names will still be unique. Post again if this assumption is not valid.
 
Old 01-26-2011, 10:31 PM   #5
grail
LQ Guru
 
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 10,007

Rep: Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191
@crts - I thought of something like yours but then thought, if the filenames are buggered maybe the directories are too, which would then cause something like yours to make the
change to the entire path. hmmm .. just thinking out loud but I guess you could get past that by using execdir??
 
Old 01-27-2011, 03:30 AM   #6
crts
Senior Member
 
Registered: Jan 2010
Posts: 2,020

Rep: Reputation: 757Reputation: 757Reputation: 757Reputation: 757Reputation: 757Reputation: 757Reputation: 757
Hi grail,

you are right. And I was considering to use -execdir at first for the same reason. But then I thought that if the OP wants to change the filenames, then maybe he also wants to change the directory names. So I went with -exec.
The main problem I see with normal -exec is in this case:
dir'with'quote/file1
dir"with"quote/file2

Afterwards file1 and file2 will be in the same directory which might be what the OP wants - or maybe not. I think some clarification from the OP is required to clear things up.

PS: If it turns out that several files will have the same name and path after renaming then I think a simple 'find' will indeed not cut it.
 
Old 01-28-2011, 03:55 AM   #7
newbash
LQ Newbie
 
Registered: Jan 2011
Posts: 2

Original Poster
Rep: Reputation: 0
Thanks all - much appreciated. The directory names are fine, it was just the filenames, so the one-liner is exactly what I need.
 
Old 01-28-2011, 05:37 AM   #8
grail
LQ Guru
 
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 10,007

Rep: Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191
Quote:
Originally Posted by crts
Hi grail,

you are right. And I was considering to use -execdir at first for the same reason. But then I thought that if the OP wants to change the filenames, then maybe he also wants to change the directory names. So I went with -exec.
The main problem I see with normal -exec is in this case:
dir'with'quote/file1
dir"with"quote/file2

Afterwards file1 and file2 will be in the same directory which might be what the OP wants - or maybe not. I think some clarification from the OP is required to clear things up.

PS: If it turns out that several files will have the same name and path after renaming then I think a simple 'find' will indeed not cut it.
Actually I think you will also run into an issue should the directory names be buggered (I realise the OP has now said they are fine) as the following would fail:
Code:
path=/var/path/this"has'quotes/file's.txt

mv $path ${path//["'\''"\"]/_}
This will crap out as it will try to look for a path like:
Code:
/var/path/this_has_quotes/file_s.txt
Which of course does not exist
 
Old 08-10-2012, 10:17 PM   #9
JakartaDean
LQ Newbie
 
Registered: Dec 2006
Location: Jakarta, Indonesia
Distribution: Fedora 6
Posts: 2

Rep: Reputation: 0
Thank you

I realize this is an old post, but wanted to pass my thanks on to all. I got a bunch of files which some moron had given filenames with the author's name, including a single quote. Frustrating to no end, until I came across this. I did try some regexp commands, but I'm not clever enough, I guess, to handle this rather special case. Very valuable.
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
[SOLVED] Using a long Bash command including single quotes and pipes in a Bash script antcore Linux - General 9 07-22-2009 11:10 AM
bash simple test with posix character class osio Programming 5 01-22-2006 07:23 PM
Using single quotes vs double quotes in PHP strings vharishankar Programming 6 07-11-2005 11:41 AM
replacing single quotes in file names adenardo Linux - General 2 05-27-2005 11:29 AM
In BASH shell, what is the difference in usage between single and double quotes? davidas Linux - Newbie 2 04-05-2004 03:00 AM

LinuxQuestions.org > Forums > Linux Forums > Linux - Newbie

All times are GMT -5. The time now is 06:16 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration