V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Distributions
Ubuntu
Fedora
CentOS
中文资源站
网易开源镜像站
patrickstar
V2EX  ›  Linux

请脚本高手帮忙写一个脚本

  •  
  •   patrickstar · 2015-12-23 09:58:21 +08:00 · 4306 次点击
    这是一个创建于 3283 天前的主题,其中的信息可能已经有所发展或是发生改变。
    需要把 linux 下的 UTF-8 编码的源程序交给别人在 Windows 上的 VS 2010 和 VS 2013 下使用,就需要把源程序(*.cpp, *.hpp, *.h)由 UTF-8 编码转换为 UTF-8 with BOM 编码,即把'\xEF\xBB\xBF'三个字节插入到一个目录(含子目录)下的所有*.cpp, *.hpp, *.h 文件头上然后放到一个新目录下,如果能发现已经是 UTF-8 with BOM 就不插入那就更好了,对于 sed 实在不熟悉

    先谢谢!
    26 条回复    2015-12-23 19:07:51 +08:00
    lululau
        1
    lululau  
       2015-12-23 10:02:11 +08:00
    201x 年的 IDE 不能设置文件编码?这种软件别惯着它
    patrickstar
        2
    patrickstar  
    OP
       2015-12-23 10:07:09 +08:00
    @lululau 不能一个一个去设置转换啊,那么多源程序文件,而且我帮别人把 VC 的 makefile 都写好了,不需要在 VS IDE 中去折腾了,只是用 VC 的编译器、链接器和运行库,但 VS 2010 的 cl.exe 不认 UTF-8 编码,必须改为 UTF-8 with BOM 编码才行
    knightlhs
        3
    knightlhs  
       2015-12-23 10:15:18 +08:00
    很多编辑器都有 save as 吧?另存为 utf8 with BOM 不就完了?不用写脚本这么费劲吧?
    lululau
        4
    lululau  
       2015-12-23 10:19:22 +08:00
    find dir xxxx -exec perl -i -pe 's#^#\xef\xbb\xbf# unless $.>1 || /^\xef\xbb\xbf/' {} \;
    hitmanx
        5
    hitmanx  
       2015-12-23 10:20:22 +08:00
    sed 什么的我也很头疼,一般这种情况我都用 python 了,尽管肯定比 sed 什么罗嗦很多.好处是即使不太会用 python,分别搜索一下 python 怎么遍历目录,怎么读写文件,怎么改编码.有 cpp 基础,几段代码拼一下也就出来了.
    kokdemo
        6
    kokdemo  
       2015-12-23 10:24:12 +08:00
    不要做伸手党。
    patrickstar
        7
    patrickstar  
    OP
       2015-12-23 10:48:12 +08:00
    @lululau 我试一试
    yougg
        8
    yougg  
       2015-12-23 11:06:30 +08:00
    不要告诉我 VS 不支持 无 BOM 的 UTF8 ?
    patrickstar
        9
    patrickstar  
    OP
       2015-12-23 11:42:27 +08:00
    @yougg VS 2010 可以支持打开,但是 cl.exe 无法正确分析代码
    patrickstar
        10
    patrickstar  
    OP
       2015-12-23 11:43:19 +08:00
    @yougg 程序里面有 “// 中文中文” 一类的注释
    z3897421
        11
    z3897421  
       2015-12-23 11:47:08 +08:00
    貌似加 BOM 的需求很少见呀...
    402124773
        12
    402124773  
       2015-12-23 11:56:49 +08:00
    @lululau
    shell+perl 估计能解决。可惜对 perl 不熟悉,看不大懂,只知道是个替换。哈哈
    find dir xxxx -exec perl -i -pe 's#^#\xef\xbb\xbf# unless $.>1 || /^\xef\xbb\xbf/' {} \;
    这个应该和 find -type -f|xags perl -i -pe 's#^#\xef\xbb\xbf# unless $.>1 || /^\xef\xbb\xbf/' {} \一样把
    ldehai
        13
    ldehai  
       2015-12-23 12:04:08 +08:00
    pynix
        14
    pynix  
       2015-12-23 12:05:59 +08:00
    BOM 没和没有差别不大吧
    nozama
        15
    nozama  
       2015-12-23 12:13:00 +08:00
    vs 坑死了....
    上次因为 //中文注释 ,编译器把注释后面一行也当成注释了。。。造成莫名其妙的 bug 。
    mv + echo + cat 就能解决吧, 简单易理解

    mv test.txt test.txt.bak
    echo -e -n "\xEF\xBB\xBF" > test.txt
    cat test.txt.bak >> test.txt

    ---
    $ file test.txt
    test.txt: UTF-8 Unicode (with BOM) text
    402124773
        16
    402124773  
       2015-12-23 12:16:58 +08:00
    @nozama
    关键是他不是所有的文件都是没带 bom 的,需要做判断。
    nozama
        17
    nozama  
       2015-12-23 12:18:00 +08:00
    @402124773 那就先 file test.txt 判断一下? :-)
    ilotuo
        18
    ilotuo  
       2015-12-23 12:22:07 +08:00
    我写过一个批量 GBK 转 UTF8 你参考一下
    ```
    find . -name "*.cpp" -exec bash -c "iconv -f GBK -t UTF-8 {} > {}.tmp;mv -f {}.tmp {}" \;

    ```
    关键是 bash 那里比较坑.具体怎么坑我也忘记了 (馆长脸
    ilotuo
        19
    ilotuo  
       2015-12-23 12:25:46 +08:00
    好吧看错需求了...orz
    无视上面
    wweir
        20
    wweir  
       2015-12-23 12:38:06 +08:00 via Android   ❤️ 1
    @nozama 继续简化
    echo -e -n "\xEF\xBB\xBF"$(cat filename) > filename
    infinity1207
        21
    infinity1207  
       2015-12-23 13:28:42 +08:00   ❤️ 1
    用 python 写了一个,你根据需要把需要 top 变量改为你需要转换编码源文件所在目录即可。

    ```
    # -*- coding: utf-8 -*-

    import os
    import binascii
    import re

    def handle(file_path):
    f = open(file_path, 'r')
    content = f.read()
    f.close()
    bom = binascii.b2a_hex(content[:3])
    if bom == 'efbbbf':
    print "%s \t have utf8 bom already." % file_path
    return;

    f = open(file_path, 'w')
    bom = binascii.a2b_hex('efbbbf')
    content = bom + content
    f.write(content)
    f.close()
    print "%s \t was added utf8 bom done." % file_path

    if __name__=='__main__':
    top = r'd:\\data'
    for root, dirs, files in os.walk(top):
    for f in files:
    m = re.search(r'(\.h)|(\.cpp)|(\.hpp)', f)
    if m:
    file_path = os.path.join(root, f)
    handle(file_path)
    ```
    infinity1207
        22
    infinity1207  
       2015-12-23 13:35:47 +08:00
    回复怎么不支持 markdown ?具体缩进看图片吧~
    Mutoo
        23
    Mutoo  
       2015-12-23 13:38:40 +08:00   ❤️ 2
    你需要的是 unix2dos
    Usage: unix2dos [options] [file ...] [-n infile outfile ...]
    -m, --add-bom add Byte Order Mark (default UTF-8)
    vus520
        24
    vus520  
       2015-12-23 13:39:50 +08:00
    @Mutoo 同意,一条命令搞定
    Mithrandir
        25
    Mithrandir  
       2015-12-23 13:47:54 +08:00
    所以微软就是喜欢干这种违反标准的事情
    patrickstar
        26
    patrickstar  
    OP
       2015-12-23 19:07:51 +08:00
    谢谢大家了,我一个一个来尝试,选一个最快捷灵活的法子
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3377 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 11:12 · PVG 19:12 · LAX 03:12 · JFK 06:12
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.