重命名文件名的一部分

我有很多这样的文件:

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

我想让它们看起来像这样:

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

我怎么能这么做?

126288 次浏览

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'`

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.

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

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.

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.

for file in *.dat ; do mv $file ${file//ABC/XYZ} ; done

No rename or sed needed. Just bash parameter expansion.