присоединиться: «Файл 2 не в отсортированном порядке»

13

У меня есть два файла _jeter3.txt и _jeter1.txt

Я проверил, что они оба отсортированы по 20-му столбцу, используя sort -c

sort -t '     ' -c -k20,20 _jeter3.txt
sort -t '     ' -c -k20,20 _jeter1.txt
#no errors

но есть ошибка, когда я хочу, чтобы joinоба файла говорит, что второй файл не отсортирован:

join -t '   ' -1 20 -2 20 _jeter1.txt _jeter3.txt > /dev/null
join: File 2 is not in sorted order

Я не понимаю почему.

cat /etc/*-release #FYI
openSUSE 11.0 (i586)
VERSION = 11.0

ОБНОВЛЕНИЕ : использование ' 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.
(...)
пьер
источник
Можете ли вы дать нам вывод "join --version" и "sort --version" только для полноты картины? Я не могу получить более старые версии gnu join, чтобы вывести это сообщение об ошибке при любых обстоятельствах.
Брюс Эдигер
3
Пожалуйста, опубликуйте некоторые примеры данных, которые показывают проблему, и вывод locale.
Жиль "ТАК - перестань быть злым"

Ответы:

25

Я получил ту же ошибку с Ubuntu 11.04, с sortи joinв версии (GNU coreutils) 8.5.

Они явно несовместимы. На самом деле sortкоманда кажется ошибочной: нет никакой разницы с опцией -f( --ignore-case) или без нее . При сортировке aaBвсегда раньше aBa. Не буквенно-цифровые символы, кажется, также всегда игнорируются ( abcраньше ab-x)

Регистрация, кажется, ожидает обратного ... Но у меня есть решение

Фактически это связано с последовательностью сортировки: использование LANG=en_EN sort -k 1,1 <myfile> ...затем LANG=en_EN join ...удаляет сообщение.

Интернационализация - корень зла ... (никто не документирует это ясно).

Майкл
источник
Так что, если оба используют LANG=en_EN, то это точно сработает? Будет ли это работать для любой локали, если обе используют одну и ту же локаль? Можно ли сказать , что разница между sortи в joinтом , что они используют другую локаль по умолчанию?
Аарон МакДейд
Это -kвариант ответа или здесь LANG=en_EN? Неясно, какое точное решение здесь.
Пользователь
5

Вы сортировали по номерам? Я обнаружил, что заполнение нулями столбца, к которому я присоединяюсь, решило эту проблему для меня.

cat file.txt \
     | awk -F"   " '{ $20=sprintf("%06s", $20); print $0}' \
     | sort > readytojoin.txt
Конор
источник
5

Если вы уверены, что правильно отсортировали свои входные файлы и их строки могут быть соединены, вы можете избежать вышеуказанной ошибки, запустив join --nocheck-order file1.txt file2.txt

Йоав Вайс
источник
4

sort по умолчанию в качестве ключа используется вся строка

join использует только указанное поле в качестве ключа.

Вы должны исправить эту несовместимость, ограничив сортировку только тем ключом, к которому вы хотите присоединиться.

Страница руководства Присоединиться заявляет:

Важно: FILE1 и FILE2 должны быть отсортированы по полям соединения. Например, используйте 'sort -k 1b, 1', если> 'join' не имеет опций. Обратите внимание, что сравнения соответствуют правилам, указанным в LC_COLLATE. Если вход> не отсортирован и некоторые строки не могут быть соединены, появится предупреждающее сообщение.

PeterVermont
источник
2
LOCALE=C sort ...
LOCALE=C join ...

Это решит вашу проблему. Проблема, как указал @Michael, заключается в последовательности сортировки, которая зависит от настроек LOCALE.

Джинеш Смарт
источник
2

Обратите внимание, что если вы видите эту ошибку, и вы уже отсортировали по конкретному столбцу и бьете головой об стену, например, sort -k4,4, то вам также может понадобиться установить разделитель для команды sort

Очевидно, OP уже сделал это с -t '', но для обычного текста, разделенного табуляцией, я бы порекомендовал

sort -t $'\t' ...

Команда сортировки может включать пробелы в качестве разделителей по умолчанию даже для чего-то, что выглядит как разделенный табуляцией файл (особенно если в столбце, по которому вы сортируете, есть пробелы).

Затем, если вы передали эти отсортированные данные, чтобы присоединиться, и у вас есть

join -t $'\t' ...

Затем это приводит к тому, что сообщение об ошибке не сортируется. Как отмечалось выше, join может не принимать -t ''.

Колин Д
источник
1

Для объединения аргумент после -t является символом. Для сортировки вы можете поставить более длинный разделитель сортировки. Я думаю, что вы можете присоединять файлы в другом поле, которое хотите, и игнорирование регистра решает проблему по совпадению.

И я согласен с Жилем, что примеры данных будут полезны.

Павел Бродацкий
источник