3

I need to rename all filenames (of varying lengths) in directory that end in ".dat.txt" to just ".txt"

INPUT:

FOO.dat.txt, FOO2.dat.txt, SPAM.dat.txt, SPAM_AND_EGGS.dat.txt

DESIRED OUTPUT:

FOO.txt, FOO2.txt, SPAM.txt, SPAM_AND_EGGS.txt

Have been trying to use "rename" but I've never used for this situation before.

for f in DIRECTORY'/'*.dat.txt do rename 's/*.dat.txt/*.txt' * done 

Thanks for your help!!!

2
  • On Windows, rename *.dat.txt *.txt does the job. Not sure if it works in sh too. Commented Jul 19, 2014 at 0:59
  • It sure doesn't. Good to know that would work on Windows side, though. Commented Jul 21, 2014 at 16:47

3 Answers 3

3

Assuming you have the rename program from the util-linux package installed:

rename .dat.txt .txt *.dat.txt 

But I think you might have the perl version instead:

rename 's/\.dat\.txt/\.txt/' *.dat.txt 

See this Linux Questions wiki page for a brief summary of the two versions.

Sign up to request clarification or add additional context in comments.

5 Comments

This only works on systems that actually have a "rename" installed.
I admit I have no idea the % of linux machines it's installed on. However, he mentions trying to use rename, so I'm assuming he has it installed. I think both our answers have a place for sure :)
In rhel and derivatives, rename is provided by util-linux package. This package provides kill, fdisk, fsck, mkfs to name a few. However, the construct of the command is subject to number of files in the directories which could potentially become too long. Maybe it is a good idea to use find, just in case. Or disable glob expansion :).
Different implementations of rename also have very different syntax.
Thanks for all the high-quality info, definitely appreciated. @chepner I added an example with the other main version of rename I found.
2

This should work:

for old in FOO*.dat.txt do new=$(echo $old | sed 's/.dat.txt/.txt/g') mv "$old" "$new" done 

2 Comments

new=${old%.dat.txt}.txt would be better than spawning an extra process to run sed.
Sort of a brute force method, but i did use a version of this.
1
for i in FOO*dat.txt; do mv "$i" "${i%%dat.txt}txt"; done 

Using bash parameter expansion: http://wiki.bash-hackers.org/syntax/pe#substring_removal

Or perhaps more elegantly:

for i in *dat.txt; do mv "$i" "${i/dat.txt/txt}"; done 

1 Comment

The second example is a bash extension and may not work in the OP's shell. The first is POSIX-compliant, so should be portable.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.