我有两个文件 _jeter3.txt 和 _jeter1.txt
我检查过它们都使用第 20 列排序 sort -c
sort -t ' ' -c -k20,20 _jeter3.txt
sort -t ' ' -c -k20,20 _jeter1.txt
#no errors
Run Code Online (Sandbox Code Playgroud)
但是当我想要join两个文件时出现错误,它说第二个文件没有排序:
join -t ' ' -1 20 -2 20 _jeter1.txt _jeter3.txt > /dev/null
join: File 2 is not in sorted order
Run Code Online (Sandbox Code Playgroud)
我不明白为什么。
cat /etc/*-release #FYI
openSUSE 11.0 (i586)
VERSION = 11.0
Run Code Online (Sandbox Code Playgroud)
更新:使用 ' sort -f' 和join -i(均不区分大小写)修复了问题。但这并不能解释我最初的问题。
更新:排序和连接的版本:
> join --version
join (GNU coreutils) 6.11
Copyright (C) 2008 Free Software Foundation, Inc.
(...)
> sort --version
sort (GNU coreutils) 6.11
Copyright (C) 2008 Free Software Foundation, Inc.
(...)
Run Code Online (Sandbox Code Playgroud)
小智 27
我在 Ubuntu 11.04sort和join版本 (GNU coreutils) 8.5 中遇到了同样的错误。
它们显然不相容。事实上,该sort命令似乎有问题:使用或不使用-f( --ignore-case) 选项没有区别。排序时,aaB总是在之前aBa。非字母数字字符似乎也总是被忽略(abc在之前ab-x)
加入似乎期望相反......但我有一个解决方案
事实上,这与整理顺序有关:使用LANG=en_EN sort -k 1,1 <myfile> ...thenLANG=en_EN join ...消除了消息。
国际化是万恶之源......(没有人清楚地记录它)。
小智 8
sort默认情况下使用整行作为键
join仅使用指定字段作为键。
您必须通过限制排序仅使用您想要加入的键来纠正这种不兼容性。
Join 手册页指出:
重要提示:FILE1 和 FILE2 必须在连接字段上排序。例如,如果 >'join' 没有选项,则使用 'sort -k 1b,1'。请注意,比较遵循“LC_COLLATE”指定的规则。如果>输入未排序并且某些行无法连接,则会给出警告消息。
请注意,如果您看到此错误,并且您已经在特定列上进行了排序,并且正在用头撞墙,例如 sort -k4,4 那么您可能还需要为排序命令设置分隔符
显然OP已经用 -t ' ' 做到了这一点,但对于普通的制表符分隔文本我建议
sort -t $'\t' ...
Run Code Online (Sandbox Code Playgroud)
默认情况下,排序命令可以将空格合并为分隔符,即使对于看起来像制表符分隔的文件的文件也是如此(特别是当您要排序的列内有空格时)。
然后,如果您将排序后的数据传递给连接,并且您有
join -t $'\t' ...
Run Code Online (Sandbox Code Playgroud)
然后这最终会导致有关它未排序的错误消息。如上所述,join 可能不接受 -t ' '。
小智 5
你是用数字排序吗?我发现对我加入的列进行零填充为我解决了这个问题。
cat file.txt \
| awk -F" " '{ $20=sprintf("%06s", $20); print $0}' \
| sort > readytojoin.txt
Run Code Online (Sandbox Code Playgroud)
小智 5
LOCALE=C sort ...
LOCALE=C join ...
Run Code Online (Sandbox Code Playgroud)
这将解决您的问题。正如@Michael 所指出的,问题是排序顺序,这取决于您的 LOCALE 设置。