bash 使用 sed 和 mv 重命名文件

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5671773/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-17 23:47:46  来源:igfitidea点击:

Rename files using sed and mv

bashsedmv

提问by tiagob

I want to rename files in the format:

我想重命名以下格式的文件:

img_MM-DD-YY_XX.jpg

img_MM-DD-YY_XXX.jpg

img_MM-DD-YY_XX.jpg

img_MM-DD-YY_XXX.jpg

to:

到:

newyears_YYYY-MM-DD_XXX.jpg

newyears_YYYY-MM-DD_XXX.jpg

Where:

在哪里:

  • YYYY = year
  • MM = month
  • DD = day
  • XXX or XX = photo number
  • YYYY = 年
  • MM = 月
  • DD = 天
  • XXX 或 XX = 照片编号

I came up with this script but it isn't working:

我想出了这个脚本,但它不起作用:

for filename in ?*.jpg; do
        newFilename=$(echo $filename | \
        sed 's/img_\(.*\)-\(.*\)-\(.*\)_\([0-9][0-9]\)\./newyears_20--_0./;
                s/img_\(.*\)-\(.*\)-\(.*\)_\([0-9][0-9][0-9]\)/newyears_20--_/' -)
        mv $filename $newFilename
done

Any help would be greatly appreciated.

任何帮助将不胜感激。

回答by anubhava

You can try this script in bash:

你可以在 bash 中尝试这个脚本:

for filename in *.jpg; do
  newFilename=$(sed -E 's#img_([0-9]{1,2})-([0-9]{1,2})-([0-9]{1,2})_(.*)$#newyears_20--_#' <<< "$filename")
  mv "$filename" "$newFilename"
done

sed -Eis supported by gnu sedalso.

sed -E也支持gnu sed

回答by earthdan

Without a for loop.

没有 for 循环。

ls | grep 'jpg$' | sed '
#Save the original filename
h
#Do the replacement
s/img_\(.*\)-\(.*\)-\(.*\)_\([0-9][0-9]\)\./newyears_20--_0.//
s/img_\(.*\)-\(.*\)-\(.*\)_\([0-9][0-9][0-9]\)/newyears_20--_//
#Bring the original filename back
x
G
s/^\(.*\)\n\(.*\)$/mv "" ""' | bash

Ommit piping to bash to see the results before mv

在 mv 之前省略管道到 bash 以查看结果

Thanks to http://www.gnu.org/software/sed/manual/sed.html#Rename-files-to-lower-case

感谢http://www.gnu.org/software/sed/manual/sed.html#Rename-files-to-lower-case

回答by Idelic

for f in *.jpg; do
  mv $f $(echo newyears_${f#img_} | sed 's/_\(..\)\.jpg/_0.jpg/')
done

回答by Larry Watanabe

I remember messing around with this sort of thing. I found it often useful to create a script that you execute to do what you want:

我记得我在处理这种事情。我发现创建一个脚本来执行你想做的事情通常很有用:

ie. output of your script would be a file like:

IE。脚本的输出将是一个文件,如:

mv   file1 file2
mv   file3 file4
.....
mv   fileN fileM

To create this, just do a ls | grep date pattern| sed script to stick mv file1 to file2> myscript

要创建它,只需执行 ls | grep 日期模式| sed脚本将 mv file1 粘贴到 file2> myscript

then just execute ./myscript

然后只需执行 ./myscript

This way you have a better look at the intermediate output to figure out what's going wrong.

通过这种方式,您可以更好地查看中间输出以找出问题所在。

回答by Jonathan Leffler

This trivial variant works for me:

这个微不足道的变体对我有用:

$ cat mapper
for filename in ?*.jpg
do
    newFilename=$(echo $filename | \
    sed -e 's/img_\(.*\)-\(.*\)-\(.*\)_\([0-9][0-9]\)\./newyears_20--_0./' \
        -e 's/img_\(.*\)-\(.*\)-\(.*\)_\([0-9][0-9][0-9]\)/newyears_20--_/')
    echo mv $filename $newFilename
done
$ echo > img_04-23-09_123.jpg
$ echo > img_08-13-08_33.jpg
$ sh mapper
mv img_04-23-09_123.jpg newyears_2009-04-23_123.jpg
mv img_08-13-08_33.jpg newyears_2008-08-13_033.jpg
$

The only difference is the use of the explicit -eoptions in place of a semi-colon.

唯一的区别是使用显式-e选项代替分号。

Tested on MacOS X 10.6.7.

在 MacOS X 10.6.7 上测试。

回答by Yi Zhao

It could be handled by a purely bash script.

它可以由纯粹的 bash 脚本处理。

for j in ?*.jpg
do
  n="newyears_20${j:10:2}-${j:4:2}-${j:7:2}";
  if [ ${j:15:1} = "." ];then
    n="${n}_0${j:13}"
  else
    n="${n}${j:12}"
  fi
  mv $j $n
done

回答by kurumi

Ruby(1.9+)

红宝石(1.9+)

$ ruby -e 'Dir["img*jpg"].each{|x|File.rename(x,x.gsub(/img_(.*?)-(.*?)-(.*?)\.jpg/,"newyears_20\2-\1-\3.jpg") )}'