【问题标题】:How to grep folder that contains UTF-16 or UTF-32 encoded files?如何 grep 包含 UTF-16 或 UTF-32 编码文件的文件夹?
【发布时间】:2020-11-07 03:00:01
【问题描述】:

在一个文件夹中存在三个相同的txt-文件,每个文件里面只有一个词:“你好”。第一个文件用UTF-8 编码,第二个文件用UTF-16 编码,最后一个文件用UTF-32 编码(所有文件都是在linux 上创建的)。但是使用 grep

grep -i "hello" *.txt

只返回一个结果,它是UTF-8-文件。 Grep 没有找到其他两个文件。

如何 grep 部分包含 UTF-16UTF-32 编码文件的文件夹?

【问题讨论】:

  • 你在搜索什么样的文字?只是 UTF-16 或更复杂(和通用解决方案)中的 ASCII 文本?
  • 如上所述,只是简单的文本。文本文件只包含一个单词:“你好”,请。见上文。
  • grep -ai 'h.e.l.l.o' [UTF16] 和 3 个点 [UTF32]。这无需知道字节序或分开 BOM 即可工作。 (最好使用\0(但在redex中包含更复杂)而不是.
  • 我很惊讶,grep -ai 'h.e.l.l.o' 找到了所有 UTF-16 文件。
  • ASCII 码 xx 在 UTF-8 中是 xx,在 UTF-16 和 00 00 00 xxxx 00 00 00 中是 00 xxxx 00(但在同一文件中的格式相同)在 UTF-32 中。这仅适用于 ASCII 字符。 \0 通常在 shell 中被忽略(它用于某些命令,例如 findxargs

标签: linux encoding grep utf-16 utf-32


【解决方案1】:

一种方式使用perl 而不是grep

$ perl -CO -Mopen="IN,:encoding(UTF-16)" -ne 'print if /hello/i' utf16_file.txt

UTF-32 文件发生明显变化。

这告诉perl 使用 UTF-8 进行输出,打开读取的文件以 UTF-16 编码,并且只打印与 // 中的正则表达式匹配的行(不区分大小写) .

或者先使用iconv转换文件:

$ iconv -f UTF-16 -t UTF-8 utf16_file.txt | grep -i hello

如果您没有简单的方法从文件名中判断它是什么编码,也许像这个脚本一样使用file 尝试猜测编码,然后iconv 转换为 UTF-8喂给 GNU grep:

#!/bin/sh

# This assumes we're running in a UTF-8 locale
to_charset=UTF-8

regexp="$1"
shift 1

for file in "$@"; do
    case "$(file "$file")" in
        *UTF-16*) charset=UTF-16;;
        *UTF-32*) charset=UTF-32;;
        *UTF-8*) charset=UTF-8;;
        *ASCII*) charset=ASCII;;
        *) echo "$file has an unknown encoding." >&2
           charset=ASCII;;
    esac
    #echo "Using $charset for $file"
    iconv -f "$charset" -t "$to_charset" "$file" | \
        grep -i -H --label "$file" "$regexp"
done

用法:smartgrep hello *.txt

【讨论】:

    猜你喜欢
    • 2012-07-23
    • 2020-08-28
    • 1970-01-01
    • 2019-02-11
    • 1970-01-01
    • 2017-02-01
    • 1970-01-01
    • 2020-01-15
    • 2013-08-04
    相关资源
    最近更新 更多