Programming This 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.
Are you new to LinuxQuestions.org? Visit the following links:
Site Howto |
Site FAQ |
Sitemap |
Register Now
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.
 |
GNU/Linux Basic Guide
This 255-page guide will provide you with the keys to understand the philosophy of free software, teach you how to use and handle it, and give you the tools required to move easily in the world of GNU/Linux. Many users and administrators will be taking their first steps with this GNU/Linux Basic guide and it will show you how to approach and solve the problems you encounter.
Click Here to receive this Complete Guide absolutely free. |
|
 |
09-10-2012, 09:35 PM
|
#1
|
|
Member
Registered: Apr 2011
Distribution: Ubuntu
Posts: 50
Rep:
|
Find/Replace shell script that replaces word with other word in text, filenames
I'm trying to write a shell script that will
1) be activated with command-line arguements (
Code:
./renamescript wordone wordtwo
)
2) recursively traverse through all the non-binary files in all the directories inside the directory where the shell script lives, replacing all instaces of the first string with the second string
3) do the above, except replace all instances of the first string with the second string in filenames (e.g. blah wordoneblah.lua would become blah wordtwoblah.lua
I don't have much in the way of shell scripting skills, so this seems impossible to me. Does anyone know how this could be done?
Last edited by yanom; 09-10-2012 at 09:35 PM.
Reason: typo
|
|
|
|
09-11-2012, 12:41 AM
|
#2
|
|
Senior Member
Registered: Oct 2005
Distribution: Gentoo, Slackware, LFS
Posts: 2,052
Rep: 
|
Using a script:
Code:
#!/bin/bash
PATTERN=$1
REPLACEMENT=$2
IFS=$'\t'
while read DIR FILE; do
echo mv "$DIR/$FILE" "$DIR/${FILE//$PATTERN/$REPLACEMENT}"
done < <(exec find -type f -printf "%h\t%f\n")
Code:
# bash script.sh abc xyz
Please see find's manual to see more options about selecting the file types.
P.S. At least tell, this is not your homework right? Well I don't really mind 
|
|
|
|
09-11-2012, 01:34 AM
|
#3
|
|
Member
Registered: Jul 2008
Distribution: Ubuntu 12.10
Posts: 139
Rep:
|
I think this will do what you want, except it does not exclude binaries:
Code:
#!/bin/bash
for infile in `find -depth -readable -writable -type f`
do
outfile=`echo $infile | sed "s/$1/$2/"`
sed "s/$1/$2/" $infile > temporary
rm $infile
mv temporary $outfile
done
Last edited by everest40; 09-11-2012 at 01:51 AM.
Reason: fixed a typo in the sed command
|
|
|
|
09-11-2012, 02:50 AM
|
#4
|
|
Bash Guru
Registered: Jun 2004
Location: Osaka, Japan
Distribution: Debian sid + kde 3.5 & 4.4
Posts: 6,589
|
1) This sounds a bit like homework. I hope you aren't trying to make us do your work for you.
2) Renaming files and processing text in them are subjects that come up repeatedly. A quick LQ search will turn up dozens of them. It should then be a simple matter to extrapolate the techniques into a single script.
Code:
for infile in `find -depth -readable -writable -type f`
do
outfile=`echo $infile | sed "s/$1/$2/"`
sed "s/$1/$2/" $infile > temporary
rm $infile
mv temporary $outfile
done
Sorry, but this is incorrect. Don't Read Lines With For. To safely use the output of find, use a while+read loop and set find to output null-terminators between the filenames.
How can I read a file (data stream, variable) line-by-line (and/or field-by-field)?
http://mywiki.wooledge.org/BashFAQ/001
Also, $(..) is highly recommended over `..`. But actually, process substitution works better in a while loop.
Finally, parameter substitution can be used instead of sed.
Code:
while IFS='' read -r -d "" infile; do
outfile=${infile//$1/$2}
sed "s/$1/$2/g" "$infile" > "$outfile"
rm "$infile"
done < <( find -depth -readable -writable -type f -print0 )
|
|
|
1 members found this post helpful.
|
09-11-2012, 04:14 AM
|
#5
|
|
Member
Registered: Jul 2008
Distribution: Ubuntu 12.10
Posts: 139
Rep:
|
Thanks for the scripting tips, David 
|
|
|
|
09-11-2012, 09:36 AM
|
#6
|
|
Member
Registered: Apr 2011
Distribution: Ubuntu
Posts: 50
Original Poster
Rep:
|
thanks, I will try these out. And no, this is not homework, despite the highly specific requests. I'm developing a game in Spring engine and wanted the ability to rename a unit. This unfortunately means going through directories of game code and objects, replacing one name with another. I needed a shell script to do this quickly.
|
|
|
|
09-11-2012, 10:02 AM
|
#7
|
|
Senior Member
Registered: Oct 2005
Distribution: Gentoo, Slackware, LFS
Posts: 2,052
Rep: 
|
@yanom: And what do you actually mean about "non-binary" files? Is it just anything that's ASCII? I think using the utility command "file" would help. You could use the output of it to compare with pattern(s) in case..esac or [[ =[=/~] ]].
|
|
|
|
09-11-2012, 07:43 PM
|
#8
|
|
Member
Registered: Apr 2011
Distribution: Ubuntu
Posts: 50
Original Poster
Rep:
|
Quote:
Originally Posted by konsolebox
@yanom: And what do you actually mean about "non-binary" files? Is it just anything that's ASCII? I think using the utility command "file" would help. You could use the output of it to compare with pattern(s) in case..esac or [[ =[=/~] ]].
|
a couple of the files are 3D models and I don't want the program messing with those and possibly corrupting them.
also, this line of code does the neccessary work of replacing the filenames:
Code:
for infile in `find . \( ! -regex '.*/\..*' \)`
do
newname=`echo $infile | sed "s/$1/$2/"`
if [ "$infile" != "$newname" ]
then
git mv $infile $newname
fi
done
now it's just necessary to edit the text in-file
Last edited by yanom; 09-11-2012 at 08:06 PM.
|
|
|
|
09-12-2012, 12:29 AM
|
#9
|
|
Senior Member
Registered: Oct 2005
Distribution: Gentoo, Slackware, LFS
Posts: 2,052
Rep: 
|
Ok.
Quote:
Originally Posted by yanom
now it's just necessary to edit the text in-file
|
Sorry I didn't get that clearly. Specifically what would you edit, and where or how?
|
|
|
|
| Thread Tools |
Search this Thread |
|
|
|
Posting Rules
|
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
HTML code is Off
|
|
|
All times are GMT -5. The time now is 11:13 PM.
|
|
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.
|
Latest Threads
LQ News
|
|