我有几个文件夹里面有一些文件,我想要对其重命名
Foo'Bar - Title
to
Title
我正在使用OS X 10.7。我查看了其他解决方案,但没有一个很好地解决了递归的问题。有什么建议吗?
我有几个文件夹里面有一些文件,我想要对其重命名
Foo'Bar - Title
to
Title
sudo install -m755 rename /usr/local/bin/rename
进行安装。因此,你可以做到这一点:find . -exec rename 's|[^/]* - ||' {} +
find . -exec rename -n 's|[^/]* - ||' {} +
find .
表示 "递归查找当前目录下的所有文件"。-type f
如果您想跳过除常规文件外的所有内容,或者 -name '*标题'
如果您只想更改以“标题”结尾的文件),但这对于您的使用并非必要。-exec
… +
表示批处理找到的文件,并尽可能多地将它们代替任何出现在 '…' 中的命令中的 {}
。rename 's|[^/]* - ||' {}
表示对于{}中的每个文件, 应用perl表达式 s|[^/]* - ||
到文件名,如果结果不同,则将其重命名为该结果。s|[^/]* - ||
表示匹配正则表达式'[^/]* -
'并将匹配项替换为''(空字符串)。[^/]* -
表示匹配以“ - ”结尾的任何非斜杠字符字符串。 因此,在 './A/FooBar - Title
'中,它将匹配'FooBar -
'。试试这个:
ls -1 * | while read f ; do mv "$f" "`echo $f | sed 's/^.* - //'`" ; done
mv
之前添加一个echo
,以确保命令看起来正确。正如abarnert在评论中指出的那样,此命令每次只能处理一个目录。ls -1 *
将为当前目录中的每个文件(和目录)输出一行(除了.
文件)。因此,它将扩展为ls -1 file1 file2 ...
,-1
告诉ls
仅列出文件名,并且每行一个文件。while read f ; ... ; done
中,它将循环,直到read f
返回零,直到达到文件结束。 read f
从标准输入读取一行(在这种情况下是来自ls -1 ...
的输出),并将其存储在指定的变量中,即f
。mv
命令,第一个参数是源文件"$f"
(请注意引号以处理带有空格等的文件名),第二个参数是目标文件名,它使用sed和`(反引号)执行所谓的命令替换,将调用括号内的命令,并用标准输出替换它。
echo $f | sed 's/^.* - //'
将当前文件$f
导入sed,它将匹配正则表达式并进行替换(在s/
中的s
),并在标准输出上输出结果。正则表达式是^.* -
,它将从字符串开头^
(称为锚定)匹配任何字符.*
,然后是-
并将其替换为空字符串(//
之间的字符串)。echo $f | sed 's/^.* - //'
" ; done 只会输出6个错误。 - abarnertfind
而不是ls
。 - Mattias Wadmanls -1
返回的内容。它不是 "A/FooBar - Title" "B/FooBar - Title",而是 "" "A:" "FooBar - Title" "" "B:" "FooBar - Title"。你可以使用 ls */*Title
,这在这里可以工作。但是,一旦匹配正确的文件,你的 mv 将把所有文件移动到 Title(而不是 A/Title 等),我想你不想要这样。 - abarnerts/^.* - //
正则表达式时,rename
会有同样的问题吗? - Mattias Wadman经过一些尝试和错误,我找到了这个解决方案,它对于解决相同的问题对我很有效。
find <dir> -name *.<oldExt> -exec rename -S .<oldExt> .<newExt> {} \;
find -exec
,但我倾向于经常使用while read
模式,因为它似乎更容易执行多个命令等操作。 - Mattias Wadmanfind . -name "*.java" -exec rename 's|\.java|\.txt|' {} +
- Noam Ben Ari