标题: [文本处理] 【已结】type “htm文件” 乱码 [打印本页]
作者: plp626 时间: 2010-6-23 19:52 标题: 【已结】type “htm文件” 乱码
我是想对网页文件用sed,find进行处理,找到我想要的链接地址,可我遇到了编码的问题。
大家可以把dos联盟http://www.cn-dos.net/forum/index.php
的网页文件脱机存盘【保存类型选择仅html】,然后在cmd下type 这个文件,里面的汉子会全成了乱码;
为了这个问题,我在网上搜索了下编码的原理,联盟论坛的源文件里有- <html>
- <head>
- <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
复制代码
说明htm文件要显示的内容在源文件中是以utf-8编码的,我从网上得知,并用winhex作实验知道:- utf-8编码的文本文件前三个字符是 ee bb bf,英文字符占一个字节,汉字占三个字节。
复制代码
我在查看联盟的网页文件,文件头没有eebbbf字样,说明从文本的方式来看源文件是ascii编码的。
那么我想,要让cmd识别htm文件里的汉子,首先得把htm的源文件里要显示的汉子转换为ascii才行,这个转换我不知道是怎么实现的,但是我知道用notepad就可以很简单的另存为ascii来实现。
========================================
1. 以上只是我个人对编码的理解,如果有误请大家指出。
2. 大家能否说下记事本转换的原理,或者提下这种转换的vbs代码或者是命令行工具【是把utf-8的htm文件转换为ascii编码的htm文件】
[ 本帖最后由 plp626 于 2010-6-23 22:07 编辑 ]
作者: CUer 时间: 2010-6-23 20:20
- grep -o "http:[^\"]\+" a.htm
复制代码
作者: CUer 时间: 2010-6-23 20:25
- sed "s/a href=/\n/g" a.htm | sed -n "s/.*\(http:[^\"]\+\).*/\1/p"
复制代码
作者: plp626 时间: 2010-6-23 20:26
原帖由 CUer 于 2010-6-23 20:20 发表
grep -o "http:[^\"]\+" a.htm
谢谢,你这个是搜索所有链接地址,但把我要的标题还有其他一些信息过滤掉了。
作者: plp626 时间: 2010-6-23 20:39
原帖由 CUer 于 2010-6-23 20:25 发表
sed "s/a href=/\n/g" a.htm | sed -n "s/.*\(http:[^\"]\+\).*/\1/p"
这个代码和grep的功能一样,还是过滤掉了我想要的很多信息,不过还是很感谢你,你的真诚值得我们每个会员学习。
作者: CUer 时间: 2010-6-23 20:46
sed和grep都能直接操作UTF-8格式的文件,它们的输出是ANSI,你想实现什么功能应该都可以做到吧。
作者: plp626 时间: 2010-6-23 20:52
原帖由 CUer 于 2010-6-23 20:46 发表
sed和grep都能直接操作UTF-8格式的文件,它们的输出是ANSI,你想实现什么功能应该都可以做到吧。
也许你理解的和我理解的不同。
sed或grep处理dos联盟的文件,比如重定向为b.htm,用type命令 查看b.htm 显示的汉子仍是乱码。
作者: zqz0012005 时间: 2010-6-23 21:31
正好前不久有一个无BOM的UTF-8转为Ansi的问题
http://www.bathome.net/viewthrea ... amp;page=1#pid54514
作者: plp626 时间: 2010-6-23 21:44
很感谢,我把你的代码转来了
这个vbs代码和concmd /o:gbk a.htm 的作用相同
但是我还是没搞懂原理,转换后的文件与源文件文件头没有变化,确实是对htm网页文件里要显示的汉子的编码进行了转换,网页里标签好像没有变化【我没来得及仔细比较】
这个vbs的脚本是怎么做到的呢,使得双击它就像是在用notepad另存为ascii ?
将当前路径下所有htm文件,转为ascii编码-
- set fso = CreateObject("Scripting.FileSystemObject")
- 'Files属性获取文件集合时,与CMD下的for遍历文件有相同的Bug:
- '如果文件名有变动,可能会重复或多次遍历
- '看来是某个API的Bug
- '所以先获取文件列表再使用保险一点
- FileList = ""
- for each oFile in fso.GetFolder(".").Files
- if LCase(fso.GetExtensionName(oFile.Path)) = LCase("htm") then
- FileList = FileList & oFile.Path & vbCrLf
- end if
- next
- Files = Split(FileList, vbCrLf)
- for i=0 to UBound(Files)-1 '最后一个元素是空的
- 'U8ToU8Bom Files(i) '如果要生成一个有BOM的文件,启用此行
- U8ToAnsi Files(i)
- next
- function U8ToU8Bom(strFile)
- dim ADOStrm
- Set ADOStrm = CreateObject("ADODB.Stream")
- ADOStrm.Type = 2
- ADOStrm.Mode = 3
- ADOStrm.CharSet = "utf-8"
- ADOStrm.Open
- ADOStrm.LoadFromFile strFile
- ADOStrm.SaveToFile strFile & ".u8.txt", 2
- ADOStrm.Close
- Set ADOStrm = Nothing
- end function
- function U8ToAnsi(strFile)
- dim ADOStrm
- dim s
- Set ADOStrm = CreateObject("ADODB.Stream")
- ADOStrm.Type = 2
- ADOStrm.Mode = 3
- ADOStrm.CharSet = "utf-8"
- ADOStrm.Open
- ADOStrm.LoadFromFile strFile
- s = ADOStrm.ReadText
- ADOStrm.Position = 0
- ADOStrm.CharSet = "gbk"
- ADOStrm.WriteText s
- ADOStrm.SetEOS
- ADOStrm.SaveToFile strFile & ".ansi.htm", 2
- ADOStrm.Close
- Set ADOStrm = Nothing
- end function
复制代码
[ 本帖最后由 plp626 于 2010-6-23 22:00 编辑 ]
作者: Batcher 时间: 2010-6-23 21:48 标题: 回复 9楼 的帖子
可能还有一点需要处理,htm的行尾是0A,需要替换成0D0A
作者: zqz0012005 时间: 2010-6-23 22:24 标题: 回复 9楼 的帖子
这个就是由ADODB.Stream组件进行转换的。
当然,根据utf-8编码的原理,也可以写出函数进行解码,只是要复杂一点,毕竟“拿来主义”方便多了。
小小纠正一下:
标准ascii码只有128个字符(0~127);IBM又扩充了128个(128~255),这128个称为扩充ASCII码,用的不多。
unicode和ansi都是字符代码的一种表示形式。(ANSI还有个意思表示一个机构)
为使计算机支持更多语言,通常使用 0x80~0xFF 范围的 2 个字节来表示 1 个字符。比如:汉字 '中' 在中文操作系统中,使用 [0xD6,0xD0] 这两个字节存储。
不同的国家和地区制定了不同的标准,由此产生了 GB2312, BIG5, JIS 等各自的编码标准。这些使用 2 个字节来代表一个字符的各种汉字延伸编码方式,称为 ANSI 编码。在简体中文系统下,ANSI 编码代表 GB2312 编码;在繁体中文系统下,ANSI 编码代表 Big5编码;在日文操作系统下,ANSI 编码代表 JIS 编码;等等。
utf-8是Unicode字符代码的一种编码方式,还有utf-7、utf-16、utf-32等等
我也了解的不多,具体的可以百度百科一下
(中国的百度百科实在太烂了,太不负责了)
欢迎光临 批处理之家 (http://bathome.net./) |
Powered by Discuz! 7.2 |