Unix 排序不接受非常规分隔符“±”作为字段分隔符

Unix 排序不接受非常规分隔符“±”作为字段分隔符

我都尝试过

... | sort -k'1,1r' -k'2,2' -t'±'

... | sort -k'1,1r' -k'2,2' -t$'\xC2\xB1'


*$> sort: ±: Invalid argument*

我希望它不是不受排序支持,只是我缺少一些转义或特殊字符处理。

我的设置是:

localhost:~ user$ locale
LANG=
LC_COLLATE="C"
LC_CTYPE="UTF-8"
LC_MESSAGES="C"
LC_MONETARY="C"
LC_NUMERIC="C"
LC_TIME="C"
LC_ALL=

localhost:~ user$ sort --version
2.3-Apple (99)

答案1

如果你看一下Apple macOS 源代码sort,它对其进行了少量修改FreeBSD 的起源

特别是,你会发现同样的-t像 FreeBSD 中一样尴尬/损坏的选项处理

            case 't':
                while (strlen(optarg) > 1) {
                    if (optarg[0] != '\\') {
                        errc(2, EINVAL, "%s", optarg);
                    }
                    optarg += 1;
                    if (*optarg == '0') {
                        *optarg = 0;
                        break;
                    }
                }

正如您所看到的,-t仅当参数为空(在这种情况下 NUL 是分隔符)或包含单个字节或者 以任意数量的\字符开头,后跟一个字节(在这种情况下,该字节被用作分隔符),或者0后跟任何内容,在这种情况下,分隔符是NUL

例子:

  • -t ''-t '\0', 或-t '\\\\\0'-t '\\0whatever以 NUL 字符为界
  • -t '\t',-t '\\\t'定界于t
  • -t '\',-t '\\\\\'以反斜杠分隔。

无论如何,分隔符只能是单个字节,这个神秘的额外处理可能只在那里,所以-t '\0'可以用来指定一个 NUL 分隔符以与 GNU 兼容sort(FreeBSDsort曾经是 GNU sort),或者可能(因为那个承诺这甚至与选项无关-t),因此-t '\\'也可以用来指定\分隔符(不是 GNU 接受的东西sort)。

所以不能使用多字节字符作为分隔符。

没有多少sort实现允许多字节字符。 GNU 或 busyboxsort也没有。但ast-open 确实sort如此。

在这里,您可以±在排序之前将 与单字节字符(最好是不太可能出现在输入中的字符,这样不会影响排序)交换,并在之后恢复。值得庆幸的是 FreeBSDtr和大概 macOStr也支持多字节字符(与 GNU 相反tr):

<input tr '±\1' '\1±' | sort -t $'\1' ... | tr '±\1' '\1±'

相关内容