сортировать по нескольким файлам в Linux - PullRequest
7 голосов
/ 08 октября 2011

У меня есть несколько (много) файлов;каждый очень большой:

file0.txt
file1.txt
file2.txt

Я не хочу объединять их в один файл, потому что результирующий файл будет 10+ Гига.Каждая строка в каждом файле содержит 40-байтовую строку.Строки довольно хорошо упорядочены (около 1:10 шагов - это уменьшение значения вместо увеличения).

Я бы хотел, чтобы строки были упорядочены.(если возможно, на месте?) Это означает, что некоторые строки из конца file0.txt будут перемещены в начало file1.txt и наоборот.

Я работаю над Linux и довольно плохо знаком с ним.Я знаю о команде sort для одного файла, но мне интересно, есть ли способ сортировки по нескольким файлам.Или, может быть, есть способ создать псевдофайл из файлов меньшего размера, который linux будет рассматривать как один файл.

Что я знаю, я могу сделать: я могу отсортировать каждый файл по отдельности и прочитать в file1.txt, чтобынайти значение, большее, чем наибольшее, в file0.txt (и аналогично захватить строки с конца file0.txt), объединить и затем отсортировать ... но это неприятно и предполагает, что никакие значения из file2.txt не принадлежат file0.txt(однако в моем случае это маловероятно)

Изменить

Чтобы было ясно, если файлы выглядят так:

f0.txt
DDD
XXX
AAA

f1.txt
BBB
FFF
CCC

f2.txt
EEE
YYY
ZZZ

Я хочу это:

f0.txt
AAA
BBB
CCC

f1.txt
DDD
EEE
FFF

f2.txt
XXX
YYY
ZZZ

Ответы [ 5 ]

15 голосов
/ 08 октября 2011

Я не знаю, какая команда выполняет сортировку на месте, но я думаю, что возможна более быстрая «сортировка слиянием»:

for file in *.txt; do
    sort -o $file $file
done
sort -m *.txt | split -d -l 1000000 - output
  • sort в цикле for обеспечивает сортировку содержимого входных файлов. Если вы не хотите перезаписывать оригинал, просто измените значение после параметра -o. (Если вы ожидаете, что файлы уже отсортированы, вы можете изменить оператор сортировки на «только для проверки»: sort -c $file || exit 1)
  • Второй sort осуществляет эффективное объединение входных файлов, сохраняя при этом сортировку вывода.
  • Это передается команде split, которая затем записывает в выходные файлы с суффиксом. Обратите внимание на символ -; это говорит split для чтения из стандартного ввода (то есть канала) вместо файла.

Кроме того, вот краткое описание того, как работает сортировка слиянием:

  1. sort читает строку из каждого файла.
  2. Он упорядочивает эти строки и выбирает ту, которая должна стоять первой. Эта строка отправляется на выход, и из файла, содержащего эту строку, читается новая строка.
  3. Повторяйте шаг 2 до тех пор, пока в любом файле не останется строк.
  4. На этом этапе вывод должен быть идеально отсортированным файлом.
  5. Прибыль!
5 голосов
/ 08 октября 2011

Это не совсем то, что вы просили, но утилита sort(1) может немного помочь, используя опцию --merge. Сортируйте каждый файл по отдельности, затем сортируйте полученную кучу файлов:

for f in file*.txt ; do sort -o $f < $f ; done
sort --merge file*.txt | split -l 100000 - sorted_file

(Это 100 000 строк на выходной файл. Возможно, это все еще слишком мало.)

4 голосов
/ 08 октября 2011

Я считаю, что это ваша лучшая ставка, используя стандартные утилиты linux:

  • сортировка каждого файла по отдельности, например, for f in file*.txt; do sort $f > sorted_$f.txt; done

  • сортирует все, используя sort -m sorted_file*.txt | split -d -l <lines> - <prefix>, где <lines> - количество строк в файле, а <prefix> - префикс имени файла. (-d указывает разделению использовать числовые суффиксы).

Параметр -m сортировки позволяет ему знать, что входные файлы уже отсортированы, поэтому он может быть разумным.

2 голосов
/ 08 октября 2011

mmap () 3 файла, так как все строки имеют длину 40 байт, вы можете легко отсортировать их по месту (SIP :-).Не забудьте про msync в конце.

1 голос
/ 08 октября 2011

Если файлы отсортированы по отдельности, вы можете использовать sort -m file*.txt, чтобы объединить их вместе - прочитайте первую строку каждого файла, выведите наименьшую и повторите.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...