+ -
当前位置:首页 → 问答吧 → Windows & Unix 文件格式之迷, 空格 与 tab 转换及其相关工具

Windows & Unix 文件格式之迷, 空格 与 tab 转换及其相关工具

时间:2007-01-11

来源:互联网

(转载请留本文完整信息)

Windows   &   Unix   文件格式之迷,   空格   与   tab   转换及其相关工具
来自:   http://www.eybuild.com
[email protected]

关键字:   DOS,   Unix   文件格式,   空格   与   tab   转换工具
              fbin   win2unix   tab2unix

摘要:   本文深入揭露   Windows   &   Unix   格式差异,   及因此而导至的各种问题.
            同时介绍了一些与之相关的查看和操作工具,   并在   Windows,   Unix   进行举例.

1.   问题提出:
      我们可能会遇到过这样一些困惑:
      (1)   如何查看一个文件或数据流的二进制格式(以十六进制格式显示)?
      (2)   为什么在   windows下编译的   shell   脚本在   Unix下不能执行?
              为什么在   windows下编辑的   C   源文件在有些   gcc   编译器下不能编译?
      (3)   为什么我在   vi   等编器下打开一个文本文件会包含   ^M,   如何把它去掉?
              为什么我在   windows   上用记事本打开   unix上的文件,   文件都不换行?
      (4)   如何删除文件行尾的   空格   或   tab?
              如何把文件中的   tab   转换成   空格,   或者把   空格   转换成   tab?
              如何只转换行首   tab   转换成   空格?
      ...

2.   分析与方案:

      (1)   如何查看一个文件的二进制格式(以十六进制格式显示)?
              查看任意文件或数据流的二进制格式,   我们非常常用.
              方法一:   在   UtraEdit   使用   Ctrl   +   H   切换到十六进制编辑模式.
                      **   注意   **   :
                      此方法一有缺陷,   它会将行末的单个 "换行符 "显示成   "回车 "   +   "换行 "   两个字符.
                      这样会使问题   (2)(3)(4)   无法用此工具正确查看.

              方法二:   使用文件或流的二进制查看工具   fbin
                      fbin   可以运行于   windows   和各种   Unix   平台,
                      如下例的命令显示文件的前48字节:

                        $   fbin   xx.c   0x30
                        filename:     'xx.c '
                        filelen   :     0x68(104),   offset:   0x38,   max   output:   0x30
                        00000000:     2369   6E63   6C75   6465   3C73   7464   696F   2E68         #include <stdio.h
                        00000010:     3E0D   0A0D   0A69   6E74   6D61   696E   2829   0D0A         > ....intmain()..
                        00000020:     7B0D   0A20   2020   2063   6861   7209   2020   2020         {..         char.

                      fbin   能准确显示文件中的每一个字节.   (更多详细实例见后文)

      (2)   为什么在   windows下编辑的   shell   脚本在   Unix下不能执行?
              为什么在   windows下编辑的   C   源文件在有些   gcc   编译器下不能编译?

              原因分析:
                      unix   的   shell   脚本不能识别   "回车符 "   (即:   CR,   '\r '),
                      Windows   文件格式(详细分析见下文)   换行时,   总是以   "回车 "   +   "换行 "
                      (可以借助上一问介绍的   fbin   工具,   查看文件中是否包含   "回车换行 "   对),
                      导到   unix   下的   shell   无法正常解释.

              解决方法:
                      就是把   windows   格式的中的   "回车 "   符删除,   删除.

              方法一:   使用   vi   打开源文件,   把   '\r\n '   替换成   '\n '
                      **   缺点   **   :   不适合大量文件的批量作业.

              方法二:   使用   UtraEdit   把   Windows   格式的文件转换成   Unix   格式.
                      (菜单)文件--> 转换--> Unix转DOS
                      **   缺点   **   :   不适合大量文件的批量作业.

              方法三:   Unix   下的   dos2unix   命令,   如   $   dos2unix   -k   xx.c
                      **   缺点   **   :
                      此方法有一致命缺陷,   它会改变原来的文件属性.
                      如一个可执行   shell   脚本的可执行属性及其它属性,   转换后都将会丢掉
                      (即使用   -k   也只是能保留住原来的日期.)
                      **   优点   **   :   适合大量普通文件本文件的批量作业.

              方法四:   win2unix   (windows,   unix   均可使用),   功能类似   dos2unix,
                      如   win2unx   xx.c   (更多详细实例见后文)
                      **   优点**     :
                      克服了   dos2unix   的所有缺点(见上),   它能保留源文件的任何属性.
                      还可以返回转换即   unix2win
                      适合大量文件的批量作业.

      (3)   为什么我在   vi   等编器下打开一个文本文件会包含   ^M,   如何把它去掉?   (见结论   4,   5)
              为什么我在   windows   上用记事本打开   unix上的文件,   文件都不换行?   (见结论   1)

              原因分析:
                      要解决这个问题,   必先弄清   unix   与   windows   文本文件的差异:
                      1)   磁盘中   Windows   文本文件总是以   "回车 "   +   "换行 "的形式进行换行的.
                      2)   磁盘中   Unix   格式的文本文件,   总是以 "换行符 "(即:   LF,   '\n ')   换行,   而非   "回车换行符 ".
                            (Unix   规定:   unix   文本文件保存到磁盘时,   总是自动把   "回车换行符 "   转换成   "回车符 "   保存,
                              输出到终端时由终端自动将将   "回车符 "   转换成   "回车换行符 "   输出.)

                      **   容易看出   **:
                      Windows   格式的文件换行时,   总是比   Unix格式的文件多一个   "回车 "   ( '\r ')   符.

                      **   结论   1   **:
                      这样在   windows   的记事本中打开   Unix   格式的文件时,   因为文件中没有   '\r ',   所以无法正常显示.
                      结果就会把所有的内容显示在同一行中.

                      **   结论   2   **:
                      UtraEdit   等工具会自动检测文件中是否包含   '\r ',   当检查行末缺少   '\r '时,   一般它会提示
                      要求进行   Unix   到   Windows   格式的转换.   (相信大家都遇到这个提示信息).

                      **   结论   3   **:
                      UtraEdit   和   vi   等工具,   在保存文件时会自动依照文件原来的格式进行保存.   即:
                      如打开的如是   windows   格式它会把文件依然按   windows   格式保存   (不进行自动转换).
                      如打开的如是   unix   格式它会把文件依然按   unix   格式保存   (不进行自动转换).

                      **   结论   4   **:
                      向   UtraEdit   打开的   Unix   格式文件中,   通过粘贴板   "粘贴 "   Windows   格式的若干片断行时
                      (或反之,   即向   Windows   格式文件中,   通过粘贴板   "粘贴 "   Unix   格式的若干片断行时),
                      代码片断中的   "回车换行符 "   "不会 "   自动转换成单个   "换行 "   符(反之亦然).
                      这样,   该文件中就会出现   "回车符 "   与   "回车换行符 "   互相夹杂.
                      即,   文件中既有单独的   "回车符 "   也有   成对的   "回车换行符 ".

                      **   结论   5   **:
                      vi   编辑器等,   既能正确显示 "规则 "的   Unix   格式文件,   也能正确显示 "规则 "的   Windows   格式文件,
                      但,   对包含单独的   "回车符 ",   同时成对的   "回车换行符 "的不规则文件   (产生原因见结论   4),
                      vi   将把回车符以   ^M   的形式显示.

              解决方法:
                      使用类似问题   2   提供的解决方法即可解决,   不再骜述.
                      将   unix   转换成   Windows   格式时,   使用   unix2dos   或   win2unix   -r(-r   代表反方向)即可.

      (4)   如何删除文件行尾的   空格   或   tab?
              如何把文件中的   tab   转换成   空格,   或者把   空格   转换成   tab?
              如何只转换行首   tab   转换成   空格?

              问题分析:
                      出于各种需要,   特别是编辑   C/C++,   Java   等源程序时,   常希望将源文件中的   tab   成空格,
                      或将空格转换成   tab,   同时删除行尾不必要的空格或   tab   等.
                      如果源程序的正文中字符串中包含 "空格 "或 "tab "时,   则只希望只转换行首的 "空格 "或 "tab ".

              解决方法:
                      如果是单个文件,   直接使用一些编辑器自带的转换功能转换.
                      如果是想批量转换,   不防试试   tab2sp   进行转换,   不仅适合批量文件,   还适合数据流.

              方法一:   使用   UtraEdit   的转换功能,   即:   (菜单)格式--> 转换   TAB   为空格,   ...
                      **   缺点   **:
                      不适合大量文件的批量作业.

              方法二:   tab2sp   (适合   windows,   各种   unix   平台),
                      如   tab2sp   -t   -w8   xx.c   (更多详细实例见后文)

                      **   优点   **:
                      适合大量文件的批量作业.
                      适应文件或流的二进制查看工具   fbin


(未完)

作者: newzy   发布时间: 2007-01-11

3.   工具详解:   fbin,   win2unix,   tab2sp   等对流或文件进行批量查看/转换
      (1)   工具简介
              fbin,   win2unix,   tab2sp   等工具对流或文件进行批量查看/转换,
              适合   Windows   和   各种   Unix   平台.

      (2)   fbin   -   查看流/文件的二进制格式

              在命令行上键入下面命令即可查看在线帮助(部分内容未列出)
                $   fbin   --help
                fbin   -   display   file   with   hex   format,   version   1.0.4
                Copyright(C)   eyBuild   Group,   2005,   2006.   All   Rights   Reserved.
                http://www.eybuild.com,   [email protected]
                Usage:   fbin   [options]   [fname   [0x][offset]   [maxlen]   |   [file1]   ...]
                      -h   --help               -   show   this   help
                      -w[num]                   -   specify   word-width   [2/4],   default   2
                      -p                             -   pause   for   every   screen
                      -v                             -   verbose   mode
                      -l                             -   process   file   list   replace   'fname '   ...
                      fname                       -   file   name   to   display
                      offset                     -   hex   number,   '0x '   is   optional.
                                                          offset   > =   0   from   the   begining   of   input   file,
                                                          offset   <   0   from   the   end   of   input   file
                      maxlen                     -   max   length   to   print

                EXAMPLES:
                      win2unix   -p   foo.bin
                print   at   most   64   (0x40)   bytes   from   offset   0x200:
                      fbin   foo.bin   0x200   0x40
                print   last   32   (0x20)   bytes   with   4-bytes   word-width:
                      fbin   -w4   foo.bin   -20
                process   file   list:
                      fbin   -v   -l   f1   f2   f3   f4   f5   f6

              例1.   查看一个文件前   64   个字节二进制:
                (Unix/Windos   执行下面命令会得到相同结果)
                $   fbin   fbin.c     0     40
                00000000:     2F2A   2066   6269   6E2E   6320   2D20   6C69   7374         /*   fbin.c   -   list
                00000010:     2066   696C   6520   7769   7468   2062   696E   6E61           file   with   binna
                00000020:     7279   2066   6F72   6D61   7420   2A2F   0A0A   2F2A         ry   format   */../*
                00000030:     2043   6F70   7972   6967   6874   2843   2920   6579           Copyright(C)   ey

              例2.   查看一个文件最后   64   个字节二进制:
                (Unix/Windos   执行下面命令会得到相同结果)
                $   fbin   fbin.c     -40
                000022D5:     2020   2061   7267   632D   2D2C   2061   7267   762B               argc--,   argv+
                000022E5:     2B3B   0A20   2020   2020   2020   2067   6F74   6F20         +;.                 goto
                000022F5:     4E45   5854   3B0A   2020   2020   7D0A   0A20   2020         NEXT;.         }..
                00002305:     2072   6574   7572   6E20   4F4B   3B0A   7D0A   0A0A           return   OK;.}...

              例3.   查看一个文件从   128   字节开始的   64   个字节二进制   (4   字节宽度):
                (Unix/Windos   执行下面命令会得到相同结果)
                $   fbin   -w4   fbin.c   40   40
                00000040:     4275696C     64204772     6F75702C     20323030           Build   Group,   200
                00000050:     352C2032     3030362E     20416C6C     20526967           5,   2006.   All   Rig
                00000060:     68747320     52657365     72766564     2E202A2F           hts   Reserved.   */
                00000070:     0A0A2F2A     0A6D6F64     69666963     6174696F           ../*.modificatio

              例4.     批量显示查找(包含子目录)到的所有文件   (4   字节宽度):
                Unix   命令:
                $   find   ../bin   -name   "*.exe "   |   xargs   fbin   -w4   -l   -v   |less
                filename:     '../bin/csp2bin.exe '
                filelen   :     0x18000(98304)
                00000000:     4D5A9000     03000000     04000000     FFFF0000           MZ..............
                00000010:     B8000000     00000000     40000000     00000000           ........@.......
                00000020:     00000000     00000000     00000000     00000000           ................
                00000030:     00000000     00000000     00000000     E0000000           ................
                00000040:     0E1FBA0E     00B409CD     21B8014C     CD215468           ........!..L.!Th
                00000050:     69732070     726F6772     616D2063     616E6E6F           is   program   canno
                00000060:     74206265     2072756E     20696E20     444F5320           t   be   run   in   DOS
                00000070:     6D6F6465     2E0D0D0A     24000000     00000000           mode....$.......
                00000080:     08A64111     4CC72F42     4CC72F42     4CC72F42           ..A.L./BL./BL./B
                00000090:     37DB2342     4EC72F42     7AE12442     4DC72F42           7.#BN./Bz.$BM./B
                000000A0:     CFDB2142     59C72F42     2ED83C42     4FC72F42           ..!BY./B.. <BO./B
                000000B0:     4CC72E42     0FC72F42     7AE12542     26C72F42           L..B../Bz.%B&./B
                000000C0:     52696368     4CC72F42     00000000     00000000           RichL./B........
                000000D0:     00000000     00000000     00000000     00000000           ................
                000000E0:     50450000     4C010300     3642A445     00000000           PE..L...6B.E....
                000000F0:     00000000     E0000F01     0B010600     00000100           ................

                00000100:     00901000     00000000     F5A80000     00100000           ................
                00000110:     00100100     00004000     00100000     00100000           ......@.........
                ...

                Windos   命令如下命令,   会得到相同结果:
                E:\>   for   /F   %I   in   ( 'dir   /w   /b   /s   /A:-D   eybuild\bin ')   do   fbin   -w2   -v   -l   %I   |   more

      (3)   win2unix   -   Windows   与   Unix   文件格式互转换工具

              在命令行上键入下面命令即可查看在线帮助(部分内容未列出)
                $   win2unix   --help
                win2unix   -   translate   file   between   windows   and   unix   format,   version   1.0.5
                Usage:   win2unix   [options]   [[src]   [dst]   |   [file1]   ...]
                      -h   --help               -   show   this   help
                      -r                             -   translate   file   from   unix   format   to   windows
                      -v                             -   verbose   mode
                      -l                             -   process   file   list   replace   'src '   &   'dst '   pair
                      src                           -   source   file   or   dectory
                      dst                           -   destination   file   or   dectory

                EXAMPLES:
                      win2unix   foo.txt
                convert   unix   to   windows   format:
                      win2unix   -r   -b   src.txt   dst.txt
                process   file   list:
                      win2unix   -v   -l   f1   f2   f3   f4   f5   f6


              例1.   Unix   格式转换成   Windows   格式:
                $   win2unx   -r   fbin.c

                查看二进制结果如下,   与fbin中的 "例1 "对比容易发现,   第3行中原来的0A0A(两个 "换行符 ")
                被转换成了   0D0A0D0A   (两对 "回车换行符 ").
                $   fbin   fbin.c     0     40
                00000000:     2F2A   2066   6269   6E2E   6320   2D20   6C69   7374         /*   fbin.c   -   list
                00000010:     2066   696C   6520   7769   7468   2062   696E   6E61           file   with   binna
                00000020:     7279   2066   6F72   6D61   7420   2A2F   0D0A   0D0A         ry   format   */....
                00000030:     2F2A   2043   6F70   7972   6967   6874   2843   2920         /*   Copyright(C)

              例2.   Windows   格式转换成   Unix   格式:
                $   win2unx     fbin.c

                查看二进制结果如下,   与   "例1 "对比容易发现,   第3行中原来的0D0A0D0A   (两对 "回车换行符 ")
                被转换成了   0A0A(两个 "换行符 ")
                $   fbin   fbin.c     0     40
                00000000:     2F2A   2066   6269   6E2E   6320   2D20   6C69   7374         /*   fbin.c   -   list
                00000010:     2066   696C   6520   7769   7468   2062   696E   6E61           file   with   binna
                00000020:     7279   2066   6F72   6D61   7420   2A2F   0A0A   2F2A         ry   format   */../*
                00000030:     2043   6F70   7972   6967   6874   2843   2920   6579           Copyright(C)   ey

              例3.   批量转换查找(包含子目录)到的所有文件:
                $   find   src   -name   "*.c "   |   xargs   win2unix   -l   -v
                convert   'win '   to   'unix '   format   ...
                src/csp2bin.c
                src/tab2sp.c
                src/fbin.c
                src/win2unix.c
                ...

                Windos   命令如下命令,   会得到相同结果:
                E:\>   for   /F   %I   in   ( 'dir   /w   /b   /s   /A:-D   src/*.c ')   do   win2unix   -v   -l   %I

(未完)

作者: newzy   发布时间: 2007-01-11

(4)   tab2sp     -   tab   与   空格的互转换

              在命令行上键入下面命令即可查看在线帮助(部分内容未列出)
                $   win2unix   --help
                tab2sp   -   convert   tabs   to   spaces   or   revert,   version   1.0.2
                Usage:   tab2sp   [options]   [[src]   [dst]   |   [file1]   ...]
                      -h   --help               -   show   this   help
                      -r                             -   convert   spaces   to   tabs
                      -p                             -   only   convert   line   prefixed   spaces   or   tabs
                      -t                             -   remove   tail   tabs   and   spaces
                      -w[num]                   -   specify   tab   width   [1-8],   default   4
                      -no                           -   don 't   do   any   convert
                      -v                             -   verbose   mode
                      -l                             -   process   file   list   replace   'src '   &   'dst '   pair
                      src                           -   source   file
                      dst                           -   destination   file

                EXAMPLES:
                      tab2sp   -r   <   foo.txt
                convert   tabs   to   spaces:
                      tab2sp   foo.txt
                convert   spaces   to   tabs   and   remove   tail   tabs,   spaces:
                      tab2sp   -r   -t   foo.txt
                only   remove   tail   tabs   and   spaces:
                      tab2sp   -no   -t   foo.txt
                process   file   list:
                      tab2sp   -v   -l   f1   f2   f3   f4   f5   f6

              例1.   将文件中的所   tab   转换成   "空格 "(默认   4   字符宽度),   并删除尾部   tab   和空格:
                $   tab2sp   -t   fbin.c

                可自行用   fbin   查看二进制结果如下,   确认是否   tab(09)   全部转成成了空格(20).
                本处不再把示例结果列出.

              例2.   将文件中的所   "空格 "   转换成   tab   (默认   4   字符宽度),   并删除尾部   tab   和空格:
                $   tab2sp   -r   -t   fbin.c

              例3.   将文件中的所   tab   转换成空格(指定为   8   字符宽度),   并删除尾部   tab   和空格:
                $   tab2sp   -t   -w8   fbin.c

              例4.   只删除文件   f1,   f2,   f3   f4   行尾的空格
                $   tab2sp   -no   -t   -l   f1   f2   f3   f4

              例5.   只转换行首   tab   为空格(指定为   8   字符宽度),   并删除尾部   tab   和空格:
                $   tab2sp   -p   -t   -l   f1   f2   f3   f4

              例6.   批量转换查找(包含子目录)到的所有文件,   命令可以自由组合:
                $   find   src   -name   "*.c "   |   xargs   tab2sp   -l   -v   -w8   -p
                convert   'tab '   to   'space '   format   ...
                src/csp2bin.c
                src/tab2sp.c
                src/fbin.c
                src/win2unix.c
                ...

                Windos   命令如下命令,   会得到相同结果:
                E:\>   for   /F   %I   in   ( 'dir   /w   /b   /s   /A:-D   src/*.c ')   do   tab2sp   -l   -v   -w8   -p   %I

(   ~完~!   )
2007.1.11

作者: newzy   发布时间: 2007-01-11

不会,帮顶

作者: UltraBejing   发布时间: 2008-04-30

顶一下

作者: zhengguoying   发布时间: 2010-03-25

好贴 呵 zhengguoying

作者: mq_525093551   发布时间: 2010-04-02

 
mq_525093551
 
(mq_525093551) 

作者: zhengguoying   发布时间: 2010-04-23

不错,值得借鉴!!

作者: wayne_xie   发布时间: 2010-04-24

所有的都过于啰嗦了 你只需要 安装个 emacs 就可以直接进行转换的

作者: lvhaipeng   发布时间: 2010-08-24