我正在尝试用空格和其他此类脚本中断字符重命名文件。
该平台是 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”的手,它仍然会在前导连字符上大吃一惊。
很确定答案就在正则表达式中。
我非常感谢可以提供的任何指导!这是我在这里的第一个问题-如果我犯了错误或礼仪错误,请告诉我。我很清楚我对正则表达式的了解很差,但我认为我已经达到了不问问题将是愚蠢的做法的地步。