У меня есть 10k + файлов общим объемом более 20 ГБ, которые мне нужно объединить в один файл.
Есть ли более быстрый способ, чем
cat input_file* >> out
?
Предпочтительным способом была бы команда bash, Python также приемлем, если не значительно медленнее.
bash
shell-script
files
cat
fsperrle
источник
источник
find
не сортирует файлы так же, как глобус оболочки.out
находится на другом диске.Ответы:
Нет, кошка, безусловно, лучший способ сделать это. Зачем использовать python, если для этого уже написана программа на C? Тем не менее, вы можете рассмотреть возможность использования
xargs
в случае, если длина командной строки превышаетARG_MAX
и вам нужно более одногоcat
. Используя инструменты GNU, это эквивалентно тому, что у вас уже есть:источник
find
каналуsort
. Без этого файлы будут перечислены в произвольном порядке (определенном файловой системой, что может быть порядком создания файла).bash
глобальные. В противном случае я не вижу случаев, когдаxargs
илиcat
не будет вести себя, как ожидалось.xargs
будет вызывать поcat
мере необходимости, чтобы избежать ошибки E2BIG в execve (2).Выделение пространства для выходного файла сначала может улучшить общую скорость, поскольку системе не придется обновлять выделение для каждой записи.
Например, если в Linux:
Еще одним преимуществом является то, что если не хватает свободного места, копия не будет предприниматься.
Если включено
btrfs
, вы можетеcopy --reflink=always
первый файл (который подразумевает отсутствие копирования данных и, следовательно, будет почти мгновенным), и добавить остальные. Если есть 10000 файлов, это, вероятно, не будет иметь большого значения, если только первый файл не очень большой.Существует обобщающий API для повторного копирования всех файлов (
BTRFS_IOC_CLONE_RANGE
ioctl
), но я не смог найти никакой утилиты, предоставляющей этот API, поэтому вам придется делать это на C (python
или на других языках, если они могут вызывать произвольныеioctl
s). ,Если исходные файлы редки или имеют большие последовательности символов NUL, вы можете создать разреженный выходной файл (экономя время и дисковое пространство) с помощью (в системах GNU):
источник
>
ни>>
, но,1<>
как я уже сказал, чтобы записать в файл.<>
это стандартный оператор перенаправления чтения / записи Bourne / POSIX. Подробности смотрите в руководстве по вашей оболочке или в спецификации POSIX . Значение по умолчаниюfd
является0
для<>
оператора (<>
коротко для0<>
, как<
коротко для0<
и>
коротких для1>
), поэтому вам нужно1
явно перенаправлять стандартный вывод. Здесь не так много, что нам нужно read + write (O_RDWR
), но мы не хотимO_TRUNC
(как в>
), который бы освободил то, что мы только что выделили.dd
помощью или через чтение.fallocate
будут сводиться на нет дополнительные издержкиfind
, даже если это будет быстрее во второй раз.btrfs
конечно, открывает некоторые интересные возможности, хотя.