如何通过shell中的unicode字符进行拆分

时间:2015-10-28 06:43:31

标签: shell unicode 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));
    }

我怎么能在shell(awk,tr或sed)中做到这一点? 我试过这个,但它不起作用:

awk -F\u007c\u001c '{print $1}' es.txt

感谢。

3 个答案:

答案 0 :(得分:1)

显然,U+007CU+001C是普通的旧7位ASCII字符,因此拆分它们实际上并不需要任何Unicode支持(除了可能处理任何ASCII不兼容的Unicode编码)您正在操作的文件;但是您的问题表明您的数据是UTF-8,因此这似乎不是这种情况.UTF-16需要分割工具专门知道并与编码兼容。 / p>

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

perl -CSD -aF'\N{U+1f4a9}' -nle 'print $F[0]' es.txt

使用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

或者,如果您要使用的工具透明地处理UTF-8,您可以使用ANSI C quoting facility of Bash指定分隔符。 Unicode支持似乎只有introduced in Bash 4.2,例如Debian Squeeze(目前是oldoldstable)没有它。

awk -F$'\U0001f4a9' '{print $1}' es.txt  # or $'\u007c' for 4-digit code points

但是,由于引用工具是单引号的形式,因此您不能(轻松)在变量中具有分隔符的代码点值。

答案 1 :(得分:0)

gawk 4.1.3

(5,)

答案 2 :(得分:0)

由于您的问题被标记为,因此有一种纯粹的方式:

declare -a o=()
pnt=0
while IFS= read -d '' -n1 c ;do
    olang=$LANG
    LANG=C
    [ "${c:0:1}" = $'\303' ] &&
        printf -v o[pnt+1] "%s" "${c}" &&
        ((pnt+=2)) ||
      printf -v o[pnt] "%s%s" "${o[pnt]}" "${c}"
    LANG=$olang
done <<<$'Il s\047agit d\047une généralité!!!\n'

包含UTF8字符和换行符的提交字符串:

declare -p o
declare -a o='([0]="Il s'\''agit d'\''une g" [1]="é" [2]="n" [3]="é" [4]="ralit" [5]="é" [6]="!!!

")'

将创建一个包含7个字符串的数组:

cat -n <(printf -- "<%s>\n" "${o[@]}")
     1      <Il s'agit d'une g>
     2      <é>
     3      <n>
     4      <é>
     5      <ralit>
     6      <é>
     7      <!!!
     8
     9      >