Я пытаюсь отсортировать файл, который слишком велик для размещения в памяти. Человек для сортировки gnu с опцией -m указывает: merge already sorted files; do not sort
. Я изо всех сил пытаюсь понять последствия этого, чтобы убедиться, что этот вид выполняет то, что я хочу. Этот пост (Сортировка в pandas для больших наборов данных) предлагает комбинацию разделения gnu и gnu sort для выполнения такой задачи, сначала разбивая файл на более мелкие части, которые поместятся в памяти, сортируя каждую из них по отдельности, а затем рекомбинируя. Мои эксперименты показывают, что эта процедура действительно работает. Тем не менее, меня беспокоит описание опции слияния в руководстве, где говорится, что она не сортируется. Для моих целей необходимо, чтобы большой файл был полностью отсортирован, а не просто объединение более мелких частей, отсортированных локально. Хотя я проверил эту процедуру на небольших примерах, и она, кажется, работает, руководство не дает мне уверенности в применении ее к моей реальной ситуации, поскольку я обеспокоен тем, что может возникнуть неожиданное поведение в ситуациях, когда уже невозможно проверить, работает ли gnu. sort работала так, как я предполагал.
Чтобы дать MWE, рассмотрите этот файл, разделенный табуляцией, который я хотел бы отсортировать:
3 4
2 5
3 1
1 3
Я пробовал следующие операции:
SortDir="/Users/aireties/Desktop/Sort_Experiments"
## sort document as a whole (in practice, this would be infeasible due to document size)
sort --field-separator=$'\t' -k 1,1 -k 2,2 "$SortDir/To_Be_Sorted.txt" -o "$SortDir/Sorted_as_Whole.txt" ## sort first by the first column values, then by the second
1 3
2 5
3 1
3 4
Это «правильное» решение при сортировке всего файла сразу (что невозможно в моем реальном случае использования).
Если я попытаюсь разбить файл на части, а затем сразу же использовать параметр -m, я получу неверный результат:
## Break file into pieces
MaxLines=2
mkdir "$SortDir/Pieces/"
split -l $MaxLines "$SortDir/To_Be_Sorted.txt" "$SortDir/Pieces/"
## Try merge sort on pieces without first sorting them
sort -m --field-separator=$'\t' -k 1,1 -k 2,2 "$SortDir/Pieces/"* -o "$SortDir/Sorted_in_Pieces1.txt"
3 1
1 3
3 4
2 5
Похоже, произошло то, что сортировка gnu только что рассмотрела две отдельные части и отсортировала их относительно первых значений друг в друге. Таким образом, в этом готовом изделии он поставил второй кусок первым, но не сделал никакой другой сортировки.
В качестве альтернативы, если я буду следовать процедуре, рекомендованной здесь (Сортировка в pandas для больших наборов данных ), то есть сначала отсортировать части, а затем объединить, я, кажется, получаю правильный результат:
for file in "$SortDir/Pieces/"* ## sorts all text files in pwd
do
sort --field-separator=$'\t' -k 1,1 -k 2,2 "$file" -o "$file"
done
sort -m --field-separator=$'\t' -k 1,1 -k 2,2 "$SortDir/Pieces/"* -o "$SortDir/Sorted_in_Pieces2.txt"
1 3
2 5
3 1
3 4
cmp --silent "$SortDir/Sorted_in_Pieces1.txt" "$SortDir/Sorted_as_Whole.txt" || echo "files are different"
# file are different
cmp --silent "$SortDir/Sorted_in_Pieces2.txt" "$SortDir/Sorted_as_Whole.txt" || echo "files are different"
Для меня камнем преткновения является то, что если фрагменты файлов большие, все еще необходимо выполнить довольно много вычислений, чтобы объединить их в один правильно отсортированный файл. Таким образом, мне трудно понять, как такой нетривиальный объем сортировки может быть описан как результат операции, которая утверждает, что она «не сортируется».
Может ли кто-нибудь просветить меня относительно того, почему руководство будет сформулировано так? Почему и как мы можем быть уверены, что сортировка gnu будет надежно выполнять заявленное при использовании опции слияния? Не намекает ли текст руководства на определенные ситуации, в которых эта процедура не даст желаемого результата?