使用Bash重命名文件,删除前缀和后缀

9
我将使用bash来重命名一堆文件,转换文件格式如下:
prefix - name - suffix.txt

转换成这样:

name.txt

为此,我编写了以下脚本:
find . -name "*.txt" | while read f
do
  mv "${f}" "${f/prefix - /}"
done

find . -name "*.txt" | while read f
do
  mv "${f}" "${f/ - suffix/}"
done

它可以工作,但我想使用一个循环来执行重命名。这是否可能?


2
如果您已经安装了rename,请尝试以下操作:https://dev59.com/CmfWa4cB1Zd3GeqPgFu7#11991049 - kev
我在 Mac 上,rename 没有默认安装。 - Óscar López
我正在使用OSX,我可以使用重命名功能。你确定它不在那里吗? - beth
@beth 是的,在我的OSX上仍然不可用。它可能已经在以后的版本中添加了(我正在使用10.8.5),或者你可能在某个时候安装了它。 - Óscar López
4个回答

10

另一种有趣的方法是使用正则表达式:

regex='prefix - (.*) - suffix.txt'
for f in *.txt; do
    [[ $f =~ $regex ]] && mv "$f" "${BASH_REMATCH[1]}.txt"
done

实际上,这里使用简单的模式“*.txt”有两个问题:

  1. 它太广泛了,可能需要将正则表达式应用于许多不匹配的文件。
  2. 如果当前目录中有很多文件,则命令行可能会溢出。

使用find会使过程更加复杂,但更正确:

find . -maxdepth 1 -regex 'prefix - .* - suffix.txt' -print0 | \
  while read -d '' -r; do
   [[ $REPLY =~ $regex ]] && mv "$REPLY" "${BASH_REMATCH[1]}.txt"
  done

我喜欢这个答案。只是评论一下:为了让最后一部分起作用,它必须写成 "${BASH_REMATCH[1]}.txt"。请修复它,我会接受这个答案。 - Óscar López

3
如果您有访问GNU sed的权限,您可以使用一些正则表达式来执行以下操作:
for i in *.txt; do mv "$i" "$(echo $i | sed -r 's/([^-]*)\s-\s(.*)\s-\s([^-]*)\.txt/\2.txt/')"; done

0
如果您已经安装了emacs,则可以使用dired功能。

bash中:

# open your dir with emacs
emacs /path/to/your/dir

emacs中:

  • 按下*%Enter\.txt$Enter以标记所有txt文件。
  • 按下%rEnter.*- \(.*\) -.*Enter\1.txtEnter进行重命名。

0
你可以使用这个:
find . -name "*.txt" -print0 | awk -v RS="\0" -v ORS="\0" '{print $0;sub(/^prefix - /,""); sub(/ - suffix.txt$/,".txt"); print $0; }' | xargs -0 -n 2 mv

可以更清晰地书写为:

find . -name "*.txt" -print0 |
awk -v RS="\0" -v ORS="\0" '{
  print $0;
  sub(/^prefix - /,""); 
  sub(/ - suffix.txt$/,".txt"); 
  print $0;
}' |
xargs -0 -n 2 mv

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接