按行的子字符串排序(不使用分隔符)

按行的子字符串排序(不使用分隔符)

我需要一些帮助来理解排序命令在以下示例中的工作原理:

猫测试文件

输入数据:

thisfilehasduplicates
thissnowhasfallen
thisduckhasdied
thishallwasfull
berthammwasaclown
fredsimmisprimeminister
fredalbaisabinman
janetyceisscottish
janeouseisenglish
janellyriswelsh

这里的目的是按前四个字符进行排序和删除重复。我读过,-k1.1,1.4通过按第一个字段的前四个字符排序来实现这一点。逗号表示具有含义的字符范围1.4,字段 1,字符 4。

排序-u -t -k1.1,1.4 测试文件

我将此版本解释为-t后跟空白,表示没有字段分隔符,但是我认为这可能意味着字段分隔符是空格,但它以某种方式干扰了 和-k标志-u,并且没有给我我想要的东西:

berthammwasaclown
fredalbaisabinman
fredsimmisprimeminister
janellyriswelsh
janeouseisenglish
janetyceisscottish
thisduckhasdied
thisfilehasduplicates
thishallwasfull
thissnowhasfallen

排序-u -k1.1,1.4测试文件

这个版本,没有-t标志确实给出了所需要的,前四个字符的重复数据删除,至少我认为这就是它正在做的事情

berthammwasaclown
fredalbaisabinman
janellyriswelsh
thisduckhasdied

我已经阅读了我的发行版(SunOS 5.10)上的手册页,但我不完全理解与-k-t标志相关的部分,特别是在关键规范中使用点表示法时。

答案1

sort -u -t -k1.1,1.4 testfile
我将此版本解释为 -t 后跟空白,表示没有字段分隔符,但是我认为这可能意味着字段分隔符是空格,

那些都不是。传递给 Unix 上的程序的参数的标记化是由 shell 定义的,而不是由程序定义的;在大多数 Unix 程序中,如果选项/标志(前导参数)需要一个值,并且您不将其作为同一参数的一部分提供,则下一个参数将用作该值。-t -k1.1,1.4用作-k1.1,1.4字段分隔符,将其截断为一个字符,即-。因此,无法-k识别选项,因此它使用默认键定义(即整行)进行排序。

GNU在这种情况下排序会给出错误,指出 'tab' 值(即 的值-t)是多字符;这种行为更有帮助,但传统或标准并不要求。在 SunOS-aka-Solaris 上,实用程序不是必需的,而且许多实用程序实际上不符合 XPG-and-POSIX,除非您指定 xpg4 或 xpg6 版本 - 是吗? -- 但在我的(现已虚拟化的)Solaris 10 测试系统上, 和/usr/bin/sort都有/usr/xpg4/bin/sort这种不太有用的行为。

如果您确实想要这个空间特点作为字段分隔符——这对于您的数据来说毫无意义,因为它不包含空格字符——您需要告诉将空格字符作为-t参数的一部分或附加参数传递:

sort -t" " -k1.1,1.4
sort -t' ' -k1.1,1.4
sort -t\  -k1.1,1.4
sort "-t " -k1.1,1.4
sort '-t ' -k1.1,1.4

sort -t " " -k1.1,1.4
sort -t ' ' -k1.1,1.4
sort -t \  -k1.1,1.4

请注意,在 Unix 类型的系统中(无论是否带有 Unix 商标品牌,SunOS 最初并非如此),“空白”通常不仅仅意味着空格字符;它还包括空格字符。它通常至少包括空间和(水平)选项卡字符,通常还有“垂直”空格,如 LF、VT、FF。标准sort只能使用单个字符作为字段分隔符,因此不能是空格。相比之下,shell 和 awk(默认情况下)使用多个空白字符来解析字段。

相关内容