2

我正在尝试用空格和其他此类脚本中断字符重命名文件。

该平台是 Ubuntu 服务器 12(带有 Bash 4),并且任何“重命名”命令的实例都是指 Prename aka Perl Rename。

我要么在编写合适的正则表达式时遇到问题,要么在从 find 命令创建有效变量时遇到问题。

这是我成熟命名的测试数据(所有文件,没有目录):

/test/-poop
/test/poopfile.txt
/test/po_________!!!!!!!! $$^^^   op.sh

(编辑)预期输出:我想将文件名更改为

/test/poop
/test/poopfile.txt
/test/po_op.sh

(/编辑)

如果我在 /test 中运行此命令:

find * -type f -exec rename -n 's/[^a-zA-Z0-9-_.]/_/g; s/_+/_/g' {} \;

我当然得到:

find: unknown predicate `-poop'

所以我改变了一些事情:(find * -> find . 以便 find 命令的结果以 ./ 为前缀)

find . -type f -exec rename -n 's/[^a-zA-Z0-9-_.]/_/g; s/_+/_/g' {} \;

哪个返回

./-poop renamed as ._-poop
./poopfile.txt as ._poopfile.txt
./po_________!!!!!!!! $$^^^   op.sh renamed as ._po_op.sh

那不好。我所有的文件现在都以 _ 为前缀,因为我的正则表达式完全按照我的指示做了。如果我不必处理带有前导“-”的文件,那么我会很好,但这正是我试图用这个脚本处理的那种事情。

这就是我卡住的地方 - 我不知道如何让我的正则表达式匹配一行中的前两个字符或“./”的第一个实例

^.{2} ## matches the first two characters in the string
^./   ## matches the ./ at the start of the line (assuming I change my delimiter from /)

但是我怎么说“不是字符串中的前两个字符并且不是 [a-zA-Z0-9.-_] 中的字符的任何内容?”

或者

我这样做完全错了吗?有没有办法可以将 find 命令的结果传递给重命名脚本,以便前导“-”不会导致 find 出错?

实际上是在考虑这些方面 - 我写了这个:

for f in $( find . -type f ); do
    p=$( printf "%s\n" "$f" | sed 's/^..//' );
    rename -n 's/[^a-zA-Z0-9-_.]/_/g; s/_+/_/g' "$p";
done

结果:

Unknown option: p
Unknown option: o
Unknown option: o
Unknown option: p
Usage: rename [-v] [-n] [-f] perlexpr [filenames]

因此,即使我可以找到将“-poop”重命名为“-poop”的手,它仍然会在前导连字符上大吃一惊。

很确定答案就在正则表达式中。

我非常感谢可以提供的任何指导!这是我在这里的第一个问题-如果我犯了错误或礼仪错误,请告诉我。我很清楚我对正则表达式的了解很差,但我认为我已经达到了不问问题将是愚蠢的做法的地步。

4

1 回答 1

3

使用rename -n -- $regex $filenames.

这里的关键是--,这是一种广泛使用的方法,表示“选项从这里结束,文件名从这里开始”。find本身不支持,但是支持rename

这里有更多细节。

于 2012-05-29T12:01:44.290 回答