前一段时间遇到一个批量修改文件名的,是一台debian文件服务器,为mac提供文件共享服务,其中的汉字部分采用编码方式(查了下资料,应该是的,没有去实际验证),具体的编码原则如下:
一个存储于linux服务器中的字符名称为Product_List:b2:fa:c6:b7:c4:bf:c2:bc,编码方式为CP936,但已经不会有中文了。编码的转换方式为:后面的两位字符就是对应CP936字符集的一个字符(半个汉字)的HEX内码,如上面文件名转换后应该为:Product_List产品目录,见下面转换方式。
内码 GB2312
00000000 B2 FA C6 B7 C4 BF C2 BC 产品目录
00000008 00 00 00 00 00 00 00 00 ........
00000008 00 00 00 00 00 00 00 00 ........
本案例中因存储结构变更,需要重新整理,同时原先的MAC平台及DEBIAN平台均已报废多久(这部分数据是存档数据),所以需要有一种手段将文件名称转换为正常的字符集。
我的思路是:先用find查找所有的含":"的文件或目录名称,再用mv将文件名中的":"批量替换为"%",最后通过convmv将字符转换为正常的CP936编码字。
因最近整理资料时发现这个案例,很郁闷的是,最终的程序方案已经早被我删除了,无法恢复出来了(亏了我这个数据恢复专家的名头了,呵呵)。只找到个草稿,先记下来,以后遇到类似情况待查。如果有更好的建议、意见,留言给我。
假设生成的sh文件名为t.sh,内容大致为:
echo >/testsh/t1.sh
echo >/testsh/t2.sh
find $1 -depth -type $2 -name "*\:*" -exec $3 {} \;|while read -r linet
do
line="`echo "$linet"|sed -e 's#)#\\\\)#g' -e 's/(/\\\\(/g' -e 's/&/\\\\&/g' -e 's/:/\\\\:/g' -e "s/'/\\\\\'/g"`"
echo "mv "$line" "`echo "$line"|sed -e 's/\:/%/g' -e 's/\^M//g'`" ;" >>/testsh/t1.sh
echo "convmv --notest --unescape "`echo "$line"|sed 's/\:/%/g'`" ;" >>/testsh/t2.sh
done
chmod +x /testsh/t1.sh
/testsh/t1.sh
chmod +x /testsh/t2.sh
echo >/testsh/t2.sh
find $1 -depth -type $2 -name "*\:*" -exec $3 {} \;|while read -r linet
do
line="`echo "$linet"|sed -e 's#)#\\\\)#g' -e 's/(/\\\\(/g' -e 's/&/\\\\&/g' -e 's/:/\\\\:/g' -e "s/'/\\\\\'/g"`"
echo "mv "$line" "`echo "$line"|sed -e 's/\:/%/g' -e 's/\^M//g'`" ;" >>/testsh/t1.sh
echo "convmv --notest --unescape "`echo "$line"|sed 's/\:/%/g'`" ;" >>/testsh/t2.sh
done
chmod +x /testsh/t1.sh
/testsh/t1.sh
chmod +x /testsh/t2.sh
/testsh/t2.sh
执行上面的sh 后,会生成t1.sh与t2.sh,先不断的执行“t.sh /data_dir d echo”,等全部执行完成后,再执行“t.sh /data_dir f echo”。
记得直正解决问题时,修正了好多问题,现在也想不太起来了,但思路还是可行的。暂时就这样记录吧。
本文转自 张宇 51CTO博客,原文链接:http://blog.51cto.com/zhangyu/136416,如需转载请自行联系原作者