Какой самый быстрый способ для нескольких файлов?

Мне интересно, есть ли способ объединить текстовые файлы unix вместе быстрее чем запуск cat?

Вот проблема, с которой я сталкиваюсь. Я строкую обработку текстового файла ~ 100G в размер. Я пытаюсь улучшить время выполнения, разбивая файл на многие сотни меньших файлов и обработки их параллельно. В конце концов, я получаю файлы обратно в порядке. Время чтения/записи файла занимает несколько часов. я хотел бы найти способ улучшить следующее:

cat file1 file2 file3 ... fileN >> newBigFile
  • Это требует удвоения дискового пространства, поскольку file1... fileN занимает 100G и то newBigFile берет еще 100 Гб, а затем file1... fileN получает удален

  • Данные уже находятся в file1... fileN, при этом cat >> вызывает чтение и писать время, когда все, что мне действительно нужно, это сотни файлов для снова появится как 1 файл...

Ответы

Ответ 1

Объединяя файлы вместе, вы можете удалить небольшие файлы по мере их добавления:

for file in file1 file2 file3 ... fileN; do
  cat "$file" >> bigFile && rm "$file"
done

Это позволит избежать необходимости удваивать пространство.

Нет другого способа волшебного создания файлов, магически связанных. API-интерфейс файловой системы просто не имеет функции, которая делает это.

Ответ 2

Если вам не нужен произвольный доступ к окончательному большому файлу (т.е. вы просто читаете его один раз от начала до конца), вы можете сделать ваши сотни промежуточных файлов отображаемыми как один. Где вы обычно делаете

$ consume big-file.txt

вместо этого

$ consume <(cat file1 file2 ... fileN)

Это использует Unix замещение процесса, иногда также называемое "анонимные именованные каналы".

Вы также можете сэкономить время и пространство, разделив ваш вход и сделав обработку одновременно; GNU Parallel имеет - переключатель труб, который будет точно это. Он также может собирать выходные данные в один большой файл, потенциально используя меньшее пространство для царапин, поскольку ему нужно только сохранить количество ядер на диске одновременно. Если вы одновременно запускаете сотни процессов одновременно, Parallel значительно улучшит вашу эффективность, позволяя вам настроить количество parallelism на ваш компьютер. Я очень рекомендую его.

Ответ 3

Быстрое, но не бесплатное решение? Получите накопитель SSD или флэш-память на базе PCIe. Если это то, что нужно делать на регулярной основе, увеличение скорости ввода-вывода диска будет самым экономичным и быстрым, что вы можете получить.

Ответ 4

Может быть, dd будет быстрее, потому что вам не придется передавать материал между кошкой и оболочкой. Что-то вроде:

mv file1 newBigFile
dd if=file2 of=newBigFile seek=$(stat -c %s newBigFile)

Ответ 5

Возможно ли, что вы просто не разделили файл? Вместо этого обработайте файл в кусках, установив указатель на файл в каждом из ваших параллельных рабочих. Если файл нужно обрабатывать линейным образом, это делает его более сложным, но он все равно может быть выполнен. Каждому работнику необходимо понять, что вместо того, чтобы начинать со смещения, которое вы ему даете, он должен сначала искать байта по байт в следующую новую строку +1. Каждый рабочий должен также понимать, что он не обрабатывает заданное количество байтов, которые вы ему даете, но должен обработать первую новую строку после заданного количества байтов, которые она назначает процессу.

Фактическое распределение и настройка указателя файла довольно просто. Если есть n рабочих, каждый из них обрабатывает байты размера файла n/file, а указатель файла начинается с рабочего числа * n/file_size.

Есть ли какая-то причина, что такого плана недостаточно?

Ответ 6

Я считаю, что это самый быстрый способ котать все файлы, содержащиеся в одной и той же папке:

$ ls [path to folder] | while read p; do cat $p; done

Ответ 7

Мне действительно нужно, чтобы сотни файлов снова отображались как 1 файл...

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

Ответ 8

Есть такая вещь, как слишком много concurrency.

Лучшим способом сделать это будет использование произвольного доступа для чтения в файл по желаемым диапазонам и никогда не разделить его и обрабатывать только количество файлов в виде количества физических CPU/ядер в машине. То есть, если это не забивает диск с помощью IOPS, тогда вы должны отрезать назад, пока диск не станет узким местом.

То, что вы делаете, генерирует тонны IOPS, и в физике нет никакой возможности.