如何在shell中按unicode字符分割

byl*_*nan 3 unicode shell awk

使用java:

File file = new File("C:/Users/Administrator/Desktop/es.txt");
    List<String> lines = FileUtils.readLines(file, "utf-8");
    for (String line : lines) {
        String[] arr = line.split("\\u007C\\u001C");
        System.out.println(arr.length);
        System.out.println(Arrays.toString(arr));
    }
Run Code Online (Sandbox Code Playgroud)

我如何在 shell(awk、tr 或 sed)中执行此操作?我已经尝试过这个,但它不起作用:

awk -F\u007c\u001c '{print $1}' es.txt
Run Code Online (Sandbox Code Playgroud)

谢谢。

tri*_*eee 7

显然,U+007CU+001C是普通的旧 7 位 ASCII 字符,因此对这些字符进行拆分实际上不需要任何 Unicode 支持(除了可能处理您正在操作的文件中的任何 ASCII 不兼容的 Unicode 编码之外;但是您的问题表明您的数据采用 UTF-8 格式,因此这里的情况似乎并非如此。UTF-16 需要拆分工具特别了解编码并与其兼容)。

假设你的问题可以解释为“如果我知道我想要分割的数字 Unicode 代码点,我如何将其传递给能够分割它的工具”,我的建议是 Perl。

perl -CSD -aF'\N{U+1f4a9}' -nle 'print $F[0]' es.txt
Run Code Online (Sandbox Code Playgroud)

使用U+1F4A9作为分隔符。(Perl 的数组是从零开始的,因此$F[0]对应于 Awk 的$1。该-a选项请求将字段拆分为数组@F;通常,Perl 不会显式地将输入拆分为字段。)如果要用作字段的代码点的十六进制代码分隔符位于 shell 变量中,显然使用双引号而不是单引号。

PIPE='007C'
FS='001C'
perl -CSD -aF"\N{U+$PIPE}\N{U+$FS}" -nle 'print $F[0]' es.txt
Run Code Online (Sandbox Code Playgroud)

或者,如果您要使用的工具透明地处理 UTF-8,您可以使用Bash 的 ANSI C 引用工具来指定分隔符。Unicode 支持似乎只在 Bash 4.2 中引入,因此 Debian Squeeze(目前是 oldoldstable)没有它。

awk -F$'\U0001f4a9' '{print $1}' es.txt  # or $'\u007c' for 4-digit code points
Run Code Online (Sandbox Code Playgroud)

但是,由于引用工具是单引号的一种形式,因此您无法(轻松)在变量中包含分隔符的代码点值。