bash 在 Linux 上将一组文件重命名为 001、002、...

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/880467/
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-09 18:11:57  来源:igfitidea点击:

Renaming a set of files to 001, 002, ... on Linux

linuxbashshellfilerename

提问by DisgruntledGoat

I originally had a set of images of the form image_001.jpg, image_002.jpg, ...

我最初有一组形式为 image_001.jpg、image_002.jpg、...

I went through them and removed several. Now I'd like to rename the leftover files back to image_001.jpg, image_002.jpg, ...

我浏览了它们并删除了几个。现在我想将剩余的文件重命名回 image_001.jpg、image_002.jpg、...

Is there a Linux command that will do this neatly? I'm familiar with rename but can't see anything to order file names like this. I'm thinking that since ls *.jpglists the files in order (with gaps), the solution would be to pass the output of that into a bash loop or something?

是否有一个 Linux 命令可以巧妙地做到这一点?我熟悉重命名,但看不到任何可以对这样的文件名进行排序的内容。我在想,由于ls *.jpg按顺序列出文件(有间隙),解决方案是将其输出传递到 bash 循环或其他什么?

采纳答案by Matthew Flaschen

If I understand right, you have e.g. image_001.jpg, image_003.jpg, image_005.jpg, and you want to rename to image_001.jpg, image_002.jpg, image_003.jpg.

如果我理解正确,您有例如 image_001.jpg、image_003.jpg、image_005.jpg,并且您想重命名为 image_001.jpg、image_002.jpg、image_003.jpg。

EDIT: This is modified to put the temp file in the current directory. As Stephan202 noted, this can make a significant difference if temp is on a different filesystem. To avoid hitting the temp file in the loop, it now goes through image*

编辑:修改后将临时文件放在当前目录中。正如 Stephan202 所指出的,如果 temp 位于不同的文件系统上,这可能会产生显着差异。为了避免循环中的临时文件,它现在通过图像*

i=1; temp=$(mktemp -p .); for file in image*
do
mv "$file" $temp;
mv $temp $(printf "image_%0.3d.jpg" $i)
i=$((i + 1))
done                                      

回答by Stephan202

A simple loop (test with echo, execute with mv):

一个简单的循环(用 测试,用echo执行mv):

I=1
for F in *; do
  echo "$F" `printf image_%03d.jpg $I`
  #mv "$F" `printf image_%03d.jpg $I` 2>/dev/null || true
  I=$((I + 1))
done

(I added 2>/dev/null || trueto suppress warnings about identical source and target files. If this is not to your liking, go with Matthew Flaschen's answer.)

(我添加2>/dev/null || true了抑制有关相同源文件和目标文件的警告。如果这不符合您的喜好,请使用Matthew Flaschen答案。)

回答by Paul Weibert

Try the following script:

尝试以下脚本:

numerate.sh

数字.sh

This code snipped should do the job:

剪下的这段代码应该可以完成这项工作:

./numerate.sh -d <your image folder> -b <start number> -L 3 -p image_ -s .jpg -o numerically -r

回答by lhunath

Some good answers here already; but some rely on hiding errors which is not a good idea (that assumes mvwill only error because of a condition that is expected - what about all the other reaons mvmight error?).

这里已经有一些很好的答案;但有些人依赖于隐藏错误,这不是一个好主意(假设mv只会因为预期的条件而出错 - 所有其他原因mv可能出错呢?)。

Moreover, it can be done a little shorter and should be better quoted:

此外,它可以做得更短一点,应该更好地引用:

for file in *; do
    printf -vsequenceImage 'image_%03d.jpg' "$((++i))"
    [[ -e $sequenceImage ]] || \
        mv "$file" "$sequenceImage"
done

Also note that you shouldn't capitalize your variablesin bash scripts.

另请注意,您不应在 bash 脚本中将变量大写

回答by ennuikiller

This does the reverse of what you are asking (taking files of the form *.jpg.001 and converting them to *.001.jpg), but can easily be modified for your purpose:

这与您所要求的相反(获取 *.jpg.001 格式的文件并将它们转换为 *.001.jpg),但可以根据您的目的轻松修改:

for file in * 

do

if [[ "$file" =~ "(.*)\.([[:alpha:]]+)\.([[:digit:]]{3,})$" ]]

then

mv "${BASH_REMATCH[0]}" "${BASH_REMATCH[1]}.${BASH_REMATCH[3]}.${BASH_REMATCH[2]}"

fi

done

回答by jess

I was going to suggest something like the above using a for loop, an iterator, cut -f1 -d "_", then mv i i.iterator. It looks like it's already covered other ways, though.

我打算使用 for 循环,迭代器,cut -f1 -d "_",然后 mv i i.iterator 来建议类似上面的内容。不过,它似乎已经涵盖了其他方式。