114

I have loads of files which look like this:

DET01-ABC-5_50-001.dat
...
DET01-ABC-5_50-0025.dat

and I want them to look like this:

DET01-XYZ-5_50-001.dat
...
DET01-XYZ-5_50-0025.dat

How can I do this?

Benjamin W.
  • 46,058
  • 19
  • 106
  • 116
not_a_geek
  • 1,157
  • 2
  • 9
  • 6

6 Answers6

192

There are a couple of variants of a rename command, in your case, it may be as simple as

rename ABC XYZ *.dat

You may have a version which takes a Perl regex;

rename 's/ABC/XYZ/' *.dat
Paul Dixon
  • 295,876
  • 54
  • 310
  • 348
165
for file in *.dat ; do mv $file ${file//ABC/XYZ} ; done

No rename or sed needed. Just bash parameter expansion.

RJ Alten
  • 2,162
  • 1
  • 14
  • 7
9

Something like this will do it. The for loop may need to be modified depending on which filenames you wish to capture.

for fspec1 in DET01-ABC-5_50-*.dat ; do
    fspec2=$(echo ${fspec1} | sed 's/-ABC-/-XYZ-/')
    mv ${fspec1} ${fspec2}
done

You should always test these scripts on copies of your data, by the way, and in totally different directories.

paxdiablo
  • 854,327
  • 234
  • 1,573
  • 1,953
  • for osx this the stuff. rename looks cool, but a brew install of rename seems to install a perl script which didn't work per the example above. Some googling indicated that rename isn't available on all linux vars and that there is infact a perl version floating about. I got about 10 minutes into trying to sort out the differences and decides - you know this answer is just easy enough :). – j03m Dec 19 '13 at 05:02
4

You'll need to learn how to use sed http://unixhelp.ed.ac.uk/CGI/man-cgi?sed

And also to use for so you can loop through your file entries http://www.cyberciti.biz/faq/bash-for-loop/

Your command will look something like this, I don't have a term beside me so I can't check

for i in `dir` do mv $i `echo $i | sed '/orig/new/g'`
Leftium
  • 16,497
  • 6
  • 64
  • 99
1

I like to do this with sed. In you case:

for x in DET01-*.dat; do
    echo $x | sed -r 's/DET01-ABC-(.+)\.dat/mv -v "\0" "DET01-XYZ-\1.dat"/'
done | sh -e

It is best to omit the "sh -e" part first to see what will be executed.

stribika
  • 3,146
  • 2
  • 23
  • 21
  • maybe I am doing something wrong, but this is doing nothing to my files? – not_a_geek Sep 08 '09 at 09:45
  • Are you trying with or without the "sh -e"? If you are trying without it is not supposed to. It just prints what will be executed ("mv -v ... ..." lines) as a chance to check if everything is ok. If you like what you see add the "sh -e". – stribika Sep 08 '09 at 17:09
  • and renaming only a part, i.e the extension? I've to rename a lot of .TTF files as .ttf... – user41063 Oct 19 '18 at 21:45
1

All of these answers are simple and good. However, I always like to add an interactive mode to these scripts so that I can find false positives.

if [[ -n $inInteractiveMode ]]
then
    echo -e -n "$oldFileName => $newFileName\nDo you want to do this change? [Y/n]: "
    read run

    [[ -z $run || "$run" == "y" || "$run" == "Y" ]] && mv "$oldFileName" "$newFileName"
fi

Or make interactive mode the default and add a force flag (-f | --force) for automated scripts or if you're feeling daring. And this doesn't slow you down too much: the default response is "yes, I do want to rename" so you can just hit the enter key at each prompt (because of the -z $run test.

Jeremy Wiebe
  • 3,894
  • 22
  • 31
Sam Bisbee
  • 4,461
  • 20
  • 25