微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

recursion地“规范化”文件名

我的意思是摆脱特殊字符的文件名等

我已经做了一个脚本,可以recursion重命名文件[http://pastebin.com/raw.PHP?i=kXeHbDQw]:

例如:之前:

THIS is my file (1).txt

运行脚本之后:

如果datestring是+或 – 5分钟

复制,然后在Bash中asynchronous移动文件

为什么不能用cat来逐行读取文件,每行都有分隔符

如何在bash脚本中模拟两个连续的ENTER键的命令?

PHP脚本执行一个Bash脚本

This-is-my-file-1.txt

好。 这里是:

但是:当我想要“完全”testing它,像这样的文件名:

¤¥¦§¨©ª«¬®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÂÃÄÅÆÇÈÊËÌÎÏÐÑÒÔÕרÙUÛUÝÞßàâãäåæçèêëìîïðñòôõ÷øùûýþÿ.txt áíüűúöőóéÁÍÜŰÚÖŐÓÉ!"#$%&'()*+,:;<=>?@[]^_`{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ''“”•–—˜™š›œžŸ¡¢£.txt

它失败[http://pastebin.com/raw.PHP?i=iu8Pwrnr]:

$ sh renamer.sh directorythathasthefiles mv: cannot stat `./áíüűúöőóéÁÍÜŰÚÖŐÓÉ!"#$%&'()*+,:;<=>?@[]^_`{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ''“”•–—˜™š›œžŸ¡¢£': No such file or directory mv: cannot stat `./áíüűúöőóéÁÍÜŰÚÖŐÓÉ!"#$%&'()*+,:;<=>?@[]^_`{|}~€‚ƒ„…†....and so on $

所以“mv”不能处理特殊的字符..:

我工作了很多小时

有人有工作吗? [也可以在这两行处理字符[文件名]?]

Bash:如何避免在一行开始空白?

发送钥匙到terminal

如何使用sed来replaceconfiguration文件的variables?

这个RegExp有什么问题?

sed模式命令

mv处理特殊字符就好了。 你的脚本没有。

没有特别的顺序:

您正在使用find查找所有目录,并分别指向每个目录。

为什么for DEPTH in...使用for DEPTH in...如果你能用一个命令完全一样的话?

find -maxdepth 100 -type d

这使得任意的深度限制是不必要的

find -type d

永远不要分析ls的输出, 特别是如果你能find处理的话

find -not -type d

确保它在最坏的情况下工作:

find -not -type d -print0 | while read -r -d '' FILENAME; do

这会停止read某些转义字符和使用换行符窒息文件名。

你正在重复整个 ls | replace ls | replace 每个单个字符的循环。 不要 – 它会杀死性能。 在每个目录中循环一次所有文件,并在一个sed命令中使用多个sed或多个替换。

sed 's/á/a/g; s/í/i/g; ...'

(我打算建议sed 'y/áí/ai/' ,但不幸的是,这似乎不适用于Unicode。也许perl -CS -Mutf8 -pe 'y/áí/ai/'会。)

你还在用ASCII码思考: “其他特殊字符 – ASCII码33 .. 255” 。 别。

现在,大多数系统都使用UTF-8编码的Unicode,它具有更广泛的“特殊”字符 – 如此之大以至于逐一列出它们变得毫无意义。 (甚至是多字节 – “e”是一个字节,“ė”是三个字节。)

真正的ASCII有128个字符。 您目前所想到的是ISO 8859字符集(有时称为“ANSI”) – 特别是ISO 8859-1。 但是它们一直到8859-16,只有“ASCII”部分保持不变。

echo -n $(command)是无用的。

有更简单的方法来找到给定路径的目录和基本名称。 例如,你可以做

directory=$(dirname "$path") oldnname=$(basename "$path") # filter $oldname mv "$path" "$directory/$newname"

不要使用egrep来检查错误。 检查程序的返回码。 (就像你已经用cd做的。)

而不是过滤掉其他错误,做…

if [[ -e $directory/$newname ]]; then echo "target already exists,skipping: $oldname -> $newname" continue else mv "$path" "$directory/$newname" fi

sed 's/------------/-/g'调用的吨可以改为一个单一的正则表达式:

sed -r 's/-{2,}/-/g'

tr [foo] [bar]中的[ ] s是不必要的。 他们只是让tr代替[ to,and ] to ] 。

真的吗?

echo "$FOLDERNAME" | sed "s/$///g"

这个怎么样?

echo "$FOLDERNAME/"

最后,使用detox

尝试像这样:

find . -print0 -type f | awk 'BEGIN {RS="x00"} { printf "%sx00",$0; gsub("[^[:alnum:]]","-"); printf "%s",$0 }' | xargs -0 -L 2 mv

使用xargs(1)将确保每个文件名都完全作为一个参数传递。 awk(1)用于在旧版本之后添加新的文件名。

还有一个窍门:sed -e's / – + / – / g'将会用一个“ – ”替代多个“ – ”。

假设你的脚本的其余部分是正确的,你的问题是你正在使用read但你应该使用read -r 。 注意反斜杠是如何消失的:

áíüűúöőóéÁÍÜŰÚÖŐÓÉ!"#$%&'()*+,:;<=>?@[]^_`{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ''“”•–—˜™š›œžŸ¡¢£.txt áíüűúöőóéÁÍÜŰÚÖŐÓÉ!"#$%&'()*+,:;<=>?@[]^_`{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ''“”•–—˜™š›œžŸ¡¢£

啊…

清理脚本的一些提示

**使用sed可以同时在多个角色上进行翻译,这样可以清理所有内容并使其更易于管理:

dev:~$ echo 'áàaieeé!.txt' | sed -e 's/[áàã]/a/g; s/[éè]/e/g' aaaieee!.txt

**而不是重命名每个更改的文件,运行所有的过滤器,然后做一个动作

$ NEWNAME='áàaieeé!.txt' $ NEWNAME="$(echo "$NEWNAME" | sed -e 's/[áàã]/a/g; s/[éè]/e/g')" $ NEWNAME="$(echo "$NEWNAME" | sed -e 's/aa*/a/g')" $ echo $NEWNAME aieee!.txt

**而不是做一个ls | read ... ls | read ...循环,使用:

for OLDNAME in $DIR/*; do blah blah blah done

**将你的路径遍历和重命名逻辑分隔成两个脚本。 一个脚本查找需要重命名文件一个脚本处理单个文件的规范化。 一旦你学习了“查找”命令,你会意识到你可以折腾第一个脚本:)

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐