LinuxQuestions.org
Help answer threads with 0 replies.
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-29-2013, 05:01 AM   #1
Rohit_4739
Member
 
Registered: Oct 2010
Distribution: Red Hat
Posts: 228

Rep: Reputation: 9
Renaming file extensions using find-xargs-sed


Hi All,

I am trying some experiments with find xargs sed and just wondering if this can be even achieved. I want to find all the ".txt" files and then change their name to ".bak"(lets say) and i want to do this using sed with xargs and not conventional "rename" command. Can anyone please help me on this. Below are the few variants i have tried but without any success.

Code:
find -type f -name "a.txt" | xargs bash -c "sed 's/dat/txt/' "
find -type f -name "a.txt" | xargs -I {} mv {} `echo {} | sed 's/txt/bak/'`
Any idea ?
 
Old 01-29-2013, 06:20 AM   #2
divyashree
Senior Member
 
Registered: Apr 2007
Location: bbsr,orissa,India
Distribution: RHEL5 ,RHEL4,CENT OS5,FEDORA,UBUNTU
Posts: 1,363

Rep: Reputation: 135Reputation: 135
This simple oneliner will do your work.

Code:
for i in `find /tmp/tes -type f -name "*.txt"`; do mv  $i `echo $i | perl -pe 's/(.*)\..*/$1.bak/'` ; done
Replace /tmp/tes with your directory name.
 
Old 01-29-2013, 06:33 AM   #3
tronayne
Senior Member
 
Registered: Oct 2003
Location: Northeastern Michigan, where Carhartt is a Designer Label
Distribution: Slackware 32- & 64-bit Stable
Posts: 3,541

Rep: Reputation: 1060Reputation: 1060Reputation: 1060Reputation: 1060Reputation: 1060Reputation: 1060Reputation: 1060Reputation: 1060
Maybe take a simpler way (there are many ways to skin this cat):
Code:
#!/bin/bash
#
#	Rename files in current tree
#
for file in $(find . -type f -name '*.txt')
do
	new_file=$(sed 's/\.txt/\.bak/' ${file})
	mv ${file} ${new_file}
done
The basic thing is that you need both the old name and the new name to mv.

Hope this helps some.
 
Old 01-29-2013, 06:43 AM   #4
TobiSGD
Moderator
 
Registered: Dec 2009
Location: Germany
Distribution: Whatever fits the task best
Posts: 17,133
Blog Entries: 2

Rep: Reputation: 4839Reputation: 4839Reputation: 4839Reputation: 4839Reputation: 4839Reputation: 4839Reputation: 4839Reputation: 4839Reputation: 4839Reputation: 4839Reputation: 4839
If you use Bash anyways there is no need for Perl or sed, Bash can handle the substitution on its own (http://www.tldp.org/LDP/abs/html/par...stitution.html):
Code:
#!/bin/bash
#
#	Rename files in current tree
#
for file in $(find . -type f -name '*.txt')
do
	mv ${file} ${file%.txt}.bak
done
 
Old 01-29-2013, 09:36 AM   #5
allend
Senior Member
 
Registered: Oct 2003
Location: Melbourne
Distribution: Slackware-current
Posts: 4,574

Rep: Reputation: 1490Reputation: 1490Reputation: 1490Reputation: 1490Reputation: 1490Reputation: 1490Reputation: 1490Reputation: 1490Reputation: 1490Reputation: 1490
If you use bash there is no need for 'find'.
Code:
#!/bin/bash
#
#	Rename files in current tree
#
shopt -s globstar

for file in **/*.txt; do
  mv "$file" "${file%.txt}.bak";
done
 
Old 01-29-2013, 08:51 PM   #6
Rohit_4739
Member
 
Registered: Oct 2010
Distribution: Red Hat
Posts: 228

Original Poster
Rep: Reputation: 9
Hello Everyone,

Well first of all thanks for all of your replies. However i am aware of all the methods that are mentioned above, my original question is IF I CAN ACHIEVE THE SAME USING a combination of FIND, XARGS and SED.


Can anyone answer that ?
 
Old 01-30-2013, 05:53 AM   #7
allend
Senior Member
 
Registered: Oct 2003
Location: Melbourne
Distribution: Slackware-current
Posts: 4,574

Rep: Reputation: 1490Reputation: 1490Reputation: 1490Reputation: 1490Reputation: 1490Reputation: 1490Reputation: 1490Reputation: 1490Reputation: 1490Reputation: 1490
Something horrible without xargs and requiring a shell supporting process substitution such as bash.
Code:
while read aline; do mv "$aline" "$(echo $aline | sed 's/txt/bak/')"; done < <(find . -name "*.txt" -print)
The problem with xargs is it only supports one command, yet you want to do a 'mv' command including an argument that requires a second command. You could put the processing in a script that becomes the xargs command.

Apart from the intellectual exercise, is there a reason for this?

Last edited by allend; 01-30-2013 at 05:56 AM.
 
Old 01-30-2013, 06:21 AM   #8
colucix
LQ Guru
 
Registered: Sep 2003
Location: Bologna
Distribution: CentOS 6.5 OpenSuSE 12.3
Posts: 10,509

Rep: Reputation: 1978Reputation: 1978Reputation: 1978Reputation: 1978Reputation: 1978Reputation: 1978Reputation: 1978Reputation: 1978Reputation: 1978Reputation: 1978Reputation: 1978
Code:
find . -name \*.txt -print0 | xargs -0 bash -c 'while [[ $# -gt 0 ]]; do mv "$1" "${1/.txt/.bak}" ; shift; done' dummy
and if you really want to use sed:
Code:
find . -name \*.txt -print0 | xargs -0 bash -c 'while [[ $# -gt 0 ]]; do mv "$1" "$(echo $1|sed s/.txt/.bak/)" ; shift; done' dummy
 
1 members found this post helpful.
Old 01-30-2013, 06:30 AM   #9
allend
Senior Member
 
Registered: Oct 2003
Location: Melbourne
Distribution: Slackware-current
Posts: 4,574

Rep: Reputation: 1490Reputation: 1490Reputation: 1490Reputation: 1490Reputation: 1490Reputation: 1490Reputation: 1490Reputation: 1490Reputation: 1490Reputation: 1490
Thanks colucix! Very instructive.
 
Old 01-30-2013, 07:04 AM   #10
colucix
LQ Guru
 
Registered: Sep 2003
Location: Bologna
Distribution: CentOS 6.5 OpenSuSE 12.3
Posts: 10,509

Rep: Reputation: 1978Reputation: 1978Reputation: 1978Reputation: 1978Reputation: 1978Reputation: 1978Reputation: 1978Reputation: 1978Reputation: 1978Reputation: 1978Reputation: 1978
Quote:
Originally Posted by allend View Post
Thanks colucix! Very instructive.
You're welcome! I prefer simple solutions like yours in post #5, anyway. Mine is like to drive a Ferrari to the local store near home!
 
Old 01-30-2013, 08:39 AM   #11
tronayne
Senior Member
 
Registered: Oct 2003
Location: Northeastern Michigan, where Carhartt is a Designer Label
Distribution: Slackware 32- & 64-bit Stable
Posts: 3,541

Rep: Reputation: 1060Reputation: 1060Reputation: 1060Reputation: 1060Reputation: 1060Reputation: 1060Reputation: 1060Reputation: 1060
Something to keep in mind as you go along is the basic purpose of xargs (which is so you don't overflow the input buffer of a following command) when your working with a large batch of input (such as what you typically get with find).

The sed editor, the streaming editor, works on entire lines either in a file or an input stream (such as files names as in your example).

With sed, you can "in-line" directives or you can create a file that contains any number of directives (commands to be executed) by sed in multiple lines to work line by line on the content of a file.

For example, this is a "sed" file that does clean-up of an all upper case and abbreviated file:
Code:
cat 401.sed
s/LOAN BALANCE/Loan Balance/g
s/PIMCO REAL RETURN FUND INST/PIMCO Real Return Fund Institutional/g
s/PIMCO TTL RETURN INSTITUTIONAL/PIMCO Total Return Instutional Fund/g
s/VANGUARD DEV MRKTS INDEX FUND/Vanguard Developed Markets Index Fund/g
s/VANGUARD EXTENDED MKT INX ADMR/Vanguard Extended Market Index Fund Admiral Shares/g
s/VANGUARD INSTITUTIONAL INDEX/Vanguard Institutional Index Fund Institutional Shares/g
s/EMPLOYEE PRE-TAX/CONTRIBUTIONS - EMPLOYEE PRE-TAX/g
s/EMPLOYER MATCH/CONTRIBUTIONS - EMPLOYER MATCH/g
s/ROLLOVER/CONTRIBUTIONS - ROLLOVER/g
s/CONVERSION LOAN FUND/Conversion Loan Fund/g
s/VANGUARD DVLPD MKTS INDEX INST/Vanguard Institutional Developed Markets Index/g
s/VANGUARD EXTENDED MKT IND I CL/Vanguard Extended Market Index Fund Institutional Shares/g
It's used by
Code:
sed -f 401.sed file_name > new_file_name
Another might be
Code:
cat ./src/maps/gnis.sed
/\<SHORT_FORM\>/d;/\<ADM[0-2]\>/p;/\<PPL\>/p;/\<PPLA\>/p;/\<PPLC\>/p;/\<PPLL\>/p
for extracting certain lines from a (really large) file containing geographic names, latitudes and longitudes for placement on a map.

All of the methods described in the above posts are, of course, valid (and some quite inventive, too). But, like many things, simpler can be better -- not always, but frequently. I've pretty much always found it useful to think in terms of making a tool that will be used more than once so I try to keep things as simple as possible with a nod toward efficiency while I'm at it. I'm not being critical here, I'm just sayin'.

Complicated stuff will come back an bite you more often than not and I've tried to avoid those -- plus, half the time I can't remember why in heck I did what I did so I try not to do stuff like that.

For your purpose, renaming files, xargs and sed probably are, well, overkill. The best of the bunch up above is the shell substring extraction (${file%.txt}.bak) -- simple, elegant and efficient.

You know, it's sort of like when all you need is a Phillips screwdriver it doesn't make a heck of lot of sense to drag out the air gun?

Hope this helps some.
 
Old 01-31-2013, 03:23 PM   #12
David the H.
Bash Guru
 
Registered: Jun 2004
Location: Osaka, Japan
Distribution: Debian sid + kde 3.5 & 4.4
Posts: 6,823

Rep: Reputation: 1960Reputation: 1960Reputation: 1960Reputation: 1960Reputation: 1960Reputation: 1960Reputation: 1960Reputation: 1960Reputation: 1960Reputation: 1960Reputation: 1960
Re posts #2, #3, & #4:

Never Read Lines With For!! Particularly when working with filenames like this. Always use a while+read loop, along with null separators whenever possible, such as with find's -print0 option.

Notice also Colucix's use of null separators with xargs too, for the same reason.

Actually though, you rarely need to use xargs in combination with find, since it has it's own built-in -exec option that can generally do the job just as well.

Here are a couple of good links about using find:
http://mywiki.wooledge.org/UsingFind
http://www.grymoire.com/Unix/Find.html
 
1 members found this post helpful.
  


Reply


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
Traverse the file system and Rename (xargs or sed?) sahil.jammu Linux - General 19 05-25-2011 10:15 AM
mass file renaming sed/awk/mv asalford Linux - General 2 01-16-2008 05:53 PM
renaming file extensions mike_stlouis Linux - Newbie 2 10-31-2007 05:28 PM
File name expansion with {} in gnu find and xargs anamericanjoe Linux - Software 2 09-16-2006 03:31 PM
bash help, renaming file extensions trey85stang Linux - General 8 07-21-2005 04:51 PM

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

All times are GMT -5. The time now is 09:03 AM.

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
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration