Regex BASH:Raplace文件名不在列表中的字符
我想创建一个列表:Regex BASH:Raplace文件名不在列表中的字符,regex,bash,filenames,Regex,Bash,Filenames,我想创建一个列表: 0123456789abcdefghijklmnopqrstuvxwyzABCDEFGHIJKLMNOPQRSTUVXWYZ-._ 然后遍历文件夹中的所有文件,将列表中不存在的文件名中的每个字符替换为下划线。 这包括空格 但是只使用Bash和GNU工具 有可能吗?是的,有可能:) 使用Perl版本的rename命令,您可以使用: rename 's/[^[:alnum:]._-]/_/g' * 仅限Bash内部构件: for file in *; do repl=
0123456789abcdefghijklmnopqrstuvxwyzABCDEFGHIJKLMNOPQRSTUVXWYZ-._
然后遍历文件夹中的所有文件,将列表中不存在的文件名中的每个字符替换为下划线。
这包括空格
但是只使用Bash和GNU工具
有可能吗?是的,有可能:)
使用Perl版本的
rename
命令,您可以使用:
rename 's/[^[:alnum:]._-]/_/g' *
仅限Bash内部构件:
for file in *; do
repl=${file//[!$permitted]/_}
case $file in "$repl") continue;; esac # skip if identical
# Safety: add a suffix to avoid overwriting
while [ -e "$repl" ]; do
repl=${repl}_
done
mv "$file" "$repl"
done
如果
$allowed
包含斜杠,则需要对其进行反斜杠转义。这非常接近-您可能只需要正确的regex如果在同一文件夹中有两个名为abc(
和abc)
的文件,重命名
不是bash内置的。据我所知,该命令有两种不同的变体,包含在不同版本的Linux中。默认情况下,它不是在FreeBSD或OSX中安装的。@ghoti不止两个。@ghoti我从来没有说过它是bash内置的,至少在Debian上是Perl脚本。但是,是的,该命令在不同的系统上有不同的版本,具有不同的功能集。问题是“仅限Bash和GNU工具”,因此这违反了该要求。(不确定你为什么会有这样的要求;如果你努力实现可移植性,GNU工具也不是无处不在的;尽管在Linux上,它们几乎是给定的。)你有一个糟糕的正则表达式:不要放连字符(-
)在一个括号表达式的中间,你可以从一个代码中包含一系列字符,从代码> z <代码>到<代码> .<代码>。perl正则表达式应该是/[^\w.-]/
值得一提的是,在Bash4中,shopt-s globstar
允许对**/*中的文件使用进行递归;是否执行
?此操作非常有效!Goota更仔细地测试一下,看看是否有异常。正如Andrea在上面评论的那样,您有可能覆盖具有类似名称的文件。@glennjackman谢谢,您说得对!我添加了一个粗略的安全措施。如何修改它以使其与find一起工作?(保持路径/文件夹名称不变,仅清理文件名)
for file in *; do
repl=${file//[!$permitted]/_}
case $file in "$repl") continue;; esac # skip if identical
# Safety: add a suffix to avoid overwriting
while [ -e "$repl" ]; do
repl=${repl}_
done
mv "$file" "$repl"
done