用Bash循环重命名多个文件。

huangapple go评论58阅读模式
英文:

Renaming multiple files with a bash loop

问题

我正在尝试将以下文件名中所有的"heat_1"替换为"heat_21",但我在编写一个简洁的正则表达式以覆盖所有四个文件时遇到了问题:

5JUP_N2_UUCGCU_heat_1.out  5JUP_N2_UUCGCU_heat_1.rst  mdcrd_heat_1  mdinfo_heat_1

我尝试了以下方法,但文件扩展名".out"和".rst"被删除了。我应该如何编写正则表达式以保留它们?

for i in ls *
do 
mv $i ${i/heat_*/heat_21}
done
英文:

I am trying to replace all instances of "heat_1" to "heat_21" in the following file names, but I am having issues with producing a consise regex that covers all four files:

5JUP_N2_UUCGCU_heat_1.out  5JUP_N2_UUCGCU_heat_1.rst  mdcrd_heat_1  mdinfo_heat_1

I did the following, but the file extensions ".out" and ".rst" got removed. How do I write the regex so that they don't get removed?

for i in ls *
do 
mv $i ${i/heat_*/heat_21}
done

答案1

得分: 1

使用Perl的独立rename(有时称为prename)命令:

rename -n 's/heat_1/heat_21/' *

输出:

rename(5JUP_N2_UUCGCU_heat_1.out, 5JUP_N2_UUCGCU_heat_21.out)
rename(5JUP_N2_UUCGCU_heat_1.rst, 5JUP_N2_UUCGCU_heat_21.rst)
rename(mdcrd_heat_1, mdcrd_heat_21)
rename(mdinfo_heat_1, mdinfo_heat_21)

如果输出看起来正常,请移除-n


使用bash

for i in *; do echo mv "$i" "${i/heat_1/heat_21}"; done

输出:

mv 5JUP_N2_UUCGCU_heat_1.out 5JUP_N2_UUCGCU_heat_21.out
mv 5JUP_N2_UUCGCU_heat_1.rst 5JUP_N2_UUCGCU_heat_21.rst
mv mdcrd_heat_1 mdcrd_heat_21
mv mdinfo_heat_1 mdinfo_heat_21

如果输出看起来正常,请移除echo

英文:

With Perl's standalone rename (or sometimes prename) command:

rename -n 's/heat_1/heat_21/' *

Output:
<pre>
rename(5JUP_N2_UUCGCU_heat_1.out, 5JUP_N2_UUCGCU_heat_21.out)
rename(5JUP_N2_UUCGCU_heat_1.rst, 5JUP_N2_UUCGCU_heat_21.rst)
rename(mdcrd_heat_1, mdcrd_heat_21)
rename(mdinfo_heat_1, mdinfo_heat_21)
</pre>

If output looks okay, remove -n.


With bash:

for i in *; do echo mv &quot;$i&quot; &quot;${i/heat_1/heat_21}&quot;; done

Output:
<pre>
mv 5JUP_N2_UUCGCU_heat_1.out 5JUP_N2_UUCGCU_heat_21.out
mv 5JUP_N2_UUCGCU_heat_1.rst 5JUP_N2_UUCGCU_heat_21.rst
mv mdcrd_heat_1 mdcrd_heat_21
mv mdinfo_heat_1 mdinfo_heat_21
</pre>

If output looks okay, remove echo.

答案2

得分: 0

在你的正则表达式中,你将 "heat_*" 更改为 "heat_21"。

因此,你正在将每个 "*string "heat_" 后面的所有字母都更改为 "heat_21"。如果你将 "heat_1" 放在文件名的中间,你会看到,在运行初始代码后,文件名的其余部分("heat_" 之后的部分)都会消失。

所以,为了解决你的问题,你应该使用正确的正则表达式:

for i in *
do
mv "$i" "${i/heat_1/heat_21}"
done

我将你正则表达式中的 "*" 替换为 "?",它代表任意字符。但是,由于你只想将 "heat_1" 替换为 "heat_21",你可以将 '?' 替换为 '1'。

英文:

In your regular expression, you are changing "heat_*" to "heat_21".

So, you are changing every occurence of string "heat_" and all letters after it to "heat_21". If you will place "heat_1" in a middle of your file name you will see, that after running your initial code, all the rest of the file name (after "heat_") will be gone.

So, to fix your problem, you should use proper regexp:

for i in *
do
mv &quot;$i&quot; &quot;${i/heat_?/heat_21}&quot;
done

I replaced * in your regular expression with ?, which stands for any character. But, since you only want to switch "heat_1" to "heat_21", you can replace '?' with '1'.

huangapple
  • 本文由 发表于 2023年6月9日 05:06:09
  • 转载请务必保留本文链接:https://go.coder-hub.com/76435691.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定