8

我想使用 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

它有效,但我想使用单个循环执行重命名。可能吗?

4

4 回答 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
于 2012-08-20T01:28:25.830 回答
3

如果您有权访问GNU sed,则可以使用一些正则表达式来执行以下操作:

for i in *.txt; do mv "$i" "$(echo $i | sed -r 's/([^-]*)\s-\s(.*)\s-\s([^-]*)\.txt/\2.txt/')"; done
于 2012-08-20T01:21:05.980 回答
0

如果你已经emacs安装了。您可以使用该dired功能。

bash

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

emacs

  • 按标记所有文件。*%Enter\.txt$Entertxt
  • 按重命名。%rEnter.*- \(.*\) -.*Enter\1.txtEnter
于 2012-08-20T03:17:07.977 回答
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
于 2012-08-20T01:29:49.137 回答