问题

由于我正在尝试编写脚本以根据某些正则表达式要求重命名大量文件,因此 iTerm2 上的命令工作正常,但相同的命令无法完成脚本中的工作。

加上我的一些文件名包含一些中文和韩文字符。(不知道是不是这个问题)

代码

所以我的代码需要三个输入:旧正则表达式、新正则表达式和需要重命名的文件。

这里不是代码:

#!/bin/bash

# we have less than 3 arguments. Print the help text:
if [ $# -lt 3 ] ; then
  cat << HELP
ren -- renames a number of files using sed regular expressions USAGE: ren 'regexp'
'replacement' files...

EXAMPLE: rename all *.HTM files into *.html:
ren 'HTM' 'html' *.HTM

HELP
  exit 0
fi

OLD="$1"
NEW="$2"
# The shift command removes one argument from the list of
# command line arguments.
shift
shift
# $@ contains now all the files:
for file in "$@"; do
  if [ -f "$file" ] ; then
    newfile=`echo "$file" | sed "s/${OLD}/${NEW}/g"`
    if [ -f "$newfile" ]; then
      echo "ERROR: $newfile exists already"
    else
      echo "renaming $file to $newfile ..."
      mv "$file" "$newfile"
    fi
  fi
done

我在 .profile 中将 bash 命令注册为:
alias ren="bash /pathtothefile/ren.sh"

测试

原文件名是“제01과.mp3”,我想把它变成“第01课.mp3”。

所以在我的脚本中,我使用:
$ ren "제\([0-9]*\)과" "第\1课" *.mp3

而且脚本中的 sed 似乎没有成功。

但是以下完全相同的内容可以替换名称:
$ echo "제01과.mp3" | sed s/"제\([0-9]*\)과\.mp3"/"第\1课\.mp3"/g

有什么想法吗?谢谢

打印结果

我在脚本中进行了以下更改,以便它可以打印进程信息:
newfile=`echo "$file" | sed "s/${OLD}/${NEW}/g"`
echo "The ${file} is changed to ${newfile}"

我的测试结果是:
The 제01과.mp3 is changed into 제01과.mp3
ERROR: 제01과.mp3 exists already

所以不存在格式问题。

更新(全部在 bash 4.2.45(2), Mac OS 10.9 下完成)

测试

当我尝试直接从 bash 执行命令时。我的意思是 for 循环。有一些有趣的事情。我首先使用以下命令将所有名称存储到 files.txt 文件中:
$ ls | grep mp3 > files.txt

并执行 sed 和 bla bla。而 bash 交互模式下的单个命令,如:
$ file="제01과.mp3"
$ echo $file | sed s/"제\([0-9]*\)과\.mp3"/"第\1课\.mp3"/g


第01课.mp3

而在以下交互模式中:
files=`cat files.txt`
for file in $files
do
    echo $file | sed s/"제\([0-9]*\)과\.mp3"/"第\1课\.mp3"/g
done

没有变化!

现在:
echo $file

给出:
$ 제30과.mp3

(只有30个文件)

问题部分

我尝试了之前有效的第一个命令:
$ echo $file | sed s/"제\([0-9]*\)과\.mp3"/"第\1课\.mp3"/g

它没有任何变化:
$ 제30과.mp3

所以我创建了一个新的新文件并再次尝试:
$ newfile="제30과.mp3"
$ echo $newfile | sed s/"제\([0-9]*\)과\.mp3"/"第\1课\.mp3"/g

它给出了正确的:
$第30课.mp3

哇奥兹...为什么!为什么 !为什么!我尝试查看 file 和 newfile 是否相同,当然,它们不是:
if [[ $file == $new ]]; then
    echo True
else
    echo False
fi

给出:
False

我猜

我想有一些编码问题,但我发现没有引用,有人可以帮忙吗?再次感谢。

更新 2

我似乎明白字符串和文件名之间存在巨大差异。具体来说,我直接使用一个变量,如:
file="제30과.mp3"

在脚本中,sed 工作正常。但是,如果变量是从 $@ 传递过来的,或者像这样设置变量:
file=./*mp3

然后 sed 无法工作。我不知道为什么。顺便说一句,mac sed 没有 -r 选项,在 ubuntu -r 不能解决我上面提到的问题。

最佳答案

合并了一些错误:

  • 为了在正则表达式中使用组,您需要在 sed 中扩展正则表达式 -r,在 grep
  • 中扩展 -E
  • 正确逃脱是一头野兽:)

  • 例子
    files="제2과.mp3 제30과.mp3"
    for file in $files
    do
        echo $file | sed -r 's/제([0-9]*)과\.mp3/第\1课.mp3/g'
    done
    

    产出
    第2课.mp3
    第30课.mp3
    

    10-07 16:43
    查看更多