我还没有成功找到 Linux 版本名称篡改者,我需要重命名 1000 个文件,以便它们在 Windows 上可读。
有谁知道有一个 Linux 程序可以做到这一点吗?
如果没有,那么脚本可能会起作用,因为我只需将文件夹中的所有文件重命名为前 16 个字符。我怀疑脚本路线可能值得继续下去,但不确定从哪里开始。
答案1
在 Debian、Ubuntu 及其衍生版本上,如果您man rename
在命令提示符下输入,您将获得重命名实用程序的手册页,该实用程序允许在重命名中使用任意类似 Perl 的正则表达式命令。
例如,这会将当前目录中的所有文件缩短(通过截断)长度为 5:
rename 's/^(.{5}).*/$1/' *
它的工作原理是捕获前五个字符,然后在替换中使用它,删除其余的字符。
另一个例子是将文件名(无扩展名)缩短为五个字符保存扩展名:
rename 's/^(.{5}).*(\..*)$/$1$2/' *
它捕捉到二组,第一个是前五个字符,第二个是扩展名。这将myCarefullyCraftedDocument.pdf
变成myCar.pdf
.
警告:用这个小心,最好在一个复制您的目录,或者首先进行备份。你被警告了!!至少,rename -n
先使用,这将告诉您在不实际执行的情况下会做什么。
答案2
您可以将冲突的文件移动到其他目录:
for i in *
do
j=${i:0:16}
if [ -e "$j" ]
then
mv "$i" /path/to/rename/later
else
mv "$i" "$j"
fi
done
答案3
您可以编写一个脚本来缩短文件名并在几行 bash 中删除 Windows 不喜欢的字符。警告,未经测试的代码,直接输入到我的浏览器中。
shopt -s dotglob extglob
for x in *; do
y=${x//+([!-!#$%&'().0-9@A-Z^_`a-z{}~])/_} # change all problematic characters to _
if [[ $y = .* ]]; then y=_${y#.}; fi # change dot files to begin with _
y=${y:0:16} # truncate names
y=${y,,} # convert to lowercase
if [[ -e $y || $y =~ ^(aux|clock\$|com[0-9]|con|lpt[0-9]|nul|prn)(\.*)?$ ]]; then
# The file exists or is a DOS/Windows reserved name.
# Change foo.bar to foo~1.bar, foo~2.bar, ... (I ignore the length restriction here)
i=1
if [[ $y =~ \. ]]; then
prefix=${y%%.*}; suffix=.${y#*.}
else
prefix=$y; suffix=
fi
y=${prefix}~$i$suffix
while [[ -e $y ]]; do
((++i))
y=${prefix}~$i$suffix
done
fi
mv -- "$x" "$y"
done
如果需要递归到子目录,请从 调用 shell 脚本find -depth -exec …
。或者使用 zsh 代替 bash;在 zsh 中,**/*(od)
递归地扩展到当前目录下的所有文件,首先是更深层次的嵌套文件。
答案4
有些系统没有该rename
命令,因此作为 paxdiablo 答案的替代方案,以下是如何使用mv
.
for f in *.pdf; do
tmp=`echo $f | sed -r 's//^(.{5}).*(\..*)$/$1$2/'`
mv -b ./"$f" ./"$tmp"
done
移动标志-b
会创建将被删除或覆盖的文件的备份。通过更改 for 循环中的 glob 模式,您可以调整它运行的文件,*
单独使用它在所有文件上运行。