LinuxQuestions.org
Download your favorite Linux distribution at LQ ISO.
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
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

Reply
 
Search this Thread
Old 09-10-2012, 09:35 PM   #1
yanom
Member
 
Registered: Apr 2011
Distribution: Ubuntu
Posts: 51

Rep: Reputation: 2
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. blahwordoneblah.lua would become blahwordtwoblah.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
 
Old 09-11-2012, 12:41 AM   #2
konsolebox
Senior Member
 
Registered: Oct 2005
Distribution: Gentoo, Slackware, LFS
Posts: 2,245
Blog Entries: 15

Rep: Reputation: 233Reputation: 233Reputation: 233
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
 
Old 09-11-2012, 01:34 AM   #3
everest40
Member
 
Registered: Jul 2008
Distribution: Ubuntu $LATESTVERSION
Posts: 164

Rep: Reputation: 66
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
 
Old 09-11-2012, 02:50 AM   #4
David the H.
Bash Guru
 
Registered: Jun 2004
Location: Osaka, Japan
Distribution: Debian sid + kde 3.5 & 4.4
Posts: 6,823

Rep: Reputation: 1949Reputation: 1949Reputation: 1949Reputation: 1949Reputation: 1949Reputation: 1949Reputation: 1949Reputation: 1949Reputation: 1949Reputation: 1949Reputation: 1949
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.
Old 09-11-2012, 04:14 AM   #5
everest40
Member
 
Registered: Jul 2008
Distribution: Ubuntu $LATESTVERSION
Posts: 164

Rep: Reputation: 66
Thanks for the scripting tips, David
 
Old 09-11-2012, 09:36 AM   #6
yanom
Member
 
Registered: Apr 2011
Distribution: Ubuntu
Posts: 51

Original Poster
Rep: Reputation: 2
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.
 
Old 09-11-2012, 10:02 AM   #7
konsolebox
Senior Member
 
Registered: Oct 2005
Distribution: Gentoo, Slackware, LFS
Posts: 2,245
Blog Entries: 15

Rep: Reputation: 233Reputation: 233Reputation: 233
@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 [[ =[=/~] ]].
 
Old 09-11-2012, 07:43 PM   #8
yanom
Member
 
Registered: Apr 2011
Distribution: Ubuntu
Posts: 51

Original Poster
Rep: Reputation: 2
Quote:
Originally Posted by konsolebox View Post
@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.
 
Old 09-12-2012, 12:29 AM   #9
konsolebox
Senior Member
 
Registered: Oct 2005
Distribution: Gentoo, Slackware, LFS
Posts: 2,245
Blog Entries: 15

Rep: Reputation: 233Reputation: 233Reputation: 233
Ok.
Quote:
Originally Posted by yanom View Post
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?
 
  


Reply

Tags
bash sed find, recursion, sed, shell script


Thread Tools Search this Thread
Search this Thread:

Advanced Search

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] How do I program in shell script for write a word if it finds another word bal_nair1 Linux - Newbie 9 04-23-2012 06:28 AM
[SOLVED] How do I program in shell script for write a word if it finds another word bal_nair1 Programming 2 04-23-2012 01:41 AM
bash shell script read file word by word part 2 justina Programming 7 01-25-2011 01:19 PM
How can i read two files word by word at a time using any loop by shell script? vaibhavs17 Programming 16 03-19-2010 03:48 AM


All times are GMT -5. The time now is 02:14 AM.

Main Menu
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
identi.ca: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration