Я пытаюсь сортировать файл, который слишком велик, чтобы вписаться в память. Человек для сортировки gnu по опции -m: merge already sorted files; do not sort
. Я изо всех сил пытаюсь понять последствия этого, чтобы убедиться, что сортировка выполняет то, что я хочу. Этот пост (Sorting in pandas for large datasets) предлагает комбинацию gnu split и gnu sort для выполнения такой задачи, например, сначала разбивая файл на более мелкие фрагменты, которые будут вписываться в память, сортируя каждую из них по отдельности, а затем рекомбинируя. Мои эксперименты пока показывают, что эта процедура действительно работает. Тем не менее, меня беспокоит описание варианта слияния в руководстве, в котором говорится, что он не сортируется. Для моих целей необходимо, чтобы большой файл был полностью отсортирован, а не просто конкатенация меньших фрагментов, которые были отсортированы локально. Хотя я проверил процедуру на небольших примерах и, похоже, это работает, в руководстве мне не хватает уверенности в применении его к моей реальной ситуации, поскольку я обеспокоен тем, что неожиданное поведение может возникнуть в ситуациях, когда уже невозможно проверить, не является ли gnu сортировка функционировала так, как я предполагал.gnu-sort - что означает ручное значение, когда он говорит, что опция merge делает «not 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
Что кажется случилось, что гну рода только рассмотрел два отдельные части и отсортировали их по отношению к первым значениям друг в друге. Таким образом, он поместил вторую часть сначала в этот готовый продукт, но не сделал никакой другой сортировки.
В качестве альтернативы, если следовать процедуре, пропагандируемых здесь (Sorting in pandas for large datasets), который сначала сортировать кусочки, а затем объединить, я, кажется, чтобы получить правильный результат:
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 будет надежно выполнять то, что она утверждает при использовании опции слияния? Является ли текст руководства каким-то образом намеком на определенные ситуации, в которых эта процедура не сможет достичь желаемого результата?