Усечение первого 100 Мбайт файла в Linux
Я имею в виду Как вы можете объединить два огромных файла с очень небольшим запасным дисковым пространством?
Я выполняю следующие действия:
- Выделите разреженный файл объединенного размера.
- Скопируйте 100 Мб из конца второго файла в конец нового файла.
- Усечь 100 Мб конца второго файла
- Loop 2 & 3 до завершения второго файла (с 2. измененным до нужного места в целевом файле).
- Сделайте 2 & 3 & 4, но с первым файлом.
Я хотел бы знать, есть ли там кто-нибудь, кто может "обрезать" данный файл в Linux? Усечение осуществляется по размеру файла, например, если файл равен 10 ГБ, я бы хотел усечь первый 100 МБ файла и оставить файл с оставшимся 9,9 ГБ. Кто-нибудь может помочь в этом?
Спасибо
Ответы
Ответ 1
Ответ, теперь это реальность с ядром Linux v3.15 (ext4/xfs)
Читайте здесь
http://man7.org/linux/man-pages/man2/fallocate.2.html
Код тестирования
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdlib.h>
#include <fcntl.h>
#ifndef FALLOC_FL_COLLAPSE_RANGE
#define FALLOC_FL_COLLAPSE_RANGE 0x08
#endif
int main(int argc, const char * argv[])
{
int ret;
char * page = malloc(4096);
int fd = open("test.txt", O_CREAT | O_TRUNC | O_RDWR, 0644);
if (fd == -1) {
free(page);
return (-1);
}
// Page A
printf("Write page A\n");
memset(page, 'A', 4096);
write(fd, page, 4096);
// Page B
printf("Write page B\n");
memset(page, 'B', 4096);
write(fd, page, 4096);
// Remove page A
ret = fallocate(fd, FALLOC_FL_COLLAPSE_RANGE, 0, 4096);
printf("Page A should be removed, ret = %d\n", ret);
close(fd);
free(page);
return (0);
}
Ответ 2
Отрезать начало файла невозможно в большинстве файловых систем, и нет общего API для этого; например, функция усечения только изменяет окончание файла.
Вы можете сделать это с некоторыми файловыми системами. Например, файловая система ext4 недавно получила ioctl, который может оказаться вам полезным: http://lwn.net/Articles/556136/
Обновление: Примерно через год после написания этого ответа в функцию fallocate
была добавлена поддержка удаления блоков из начала и середины файлов в файловых системах ext4 и xfs с FALLOC_FL_COLLAPSE_RANGE
режима FALLOC_FL_COLLAPSE_RANGE
. Это удобнее, чем использовать iotcl низкого уровня самостоятельно.
Там также утилита командной строки с тем же именем, что и функция C. Если ваш файл находится в поддерживаемой файловой системе, это приведет к удалению первых 100 МБ:
fallocate -c -o 0 -l 100MB yourfile
Ответ 3
Пожалуйста, прочитайте хорошую книгу программирования Linux, например. Расширенное программирование Linux.
Вам нужно использовать ядро Linux syscalls, см. syscalls (2)
В частности truncate (2) (как для усечения, так и для расширения разреженного файла на поддерживаемых им файловых системах) и stat (2), чтобы заметно получить размер файла.
Нет (переносимый или файловой системы) способ удаления байтов с начала (или в середине) файла, вы можете обрезать файл только в конце.
Ответ 4
Если вы можете работать с ASCII-строками, а не с байтами, то удалить первые n строк файла легко. Например, чтобы удалить первые 100 строк:
sed -i 1,100d /path/to/file
Ответ 5
Это довольно старый вопрос, но вот мой подход к нему. Исключая требование о том, чтобы это было сделано с ограниченным пространством, я использовал бы что-то похожее на следующее, чтобы усечь первый 100mb файла:
$ tail --bytes=$(expr $(wc -c < logfile.log) - 104857600) logfile.log > logfile.log.tmp
$ mv logfile.log.tmp logfile.log
Пояснение:
- Это выводит последние nn байты файла (tail -bytes).
- Количество байтов в выводимом файле рассчитывается как размер файла (wc -c < logfile.log) минус 100 Мб (expr $(...) - 104857600). Это оставило бы нас с 100 Мб меньше размера файла, чтобы взять хвост (например, 9.9 ГБ)
- Затем он выводится в файл temp и затем возвращается к исходному имени файла, чтобы оставить усеченный файл.
Ответ 6
удалить все, кроме последних 10000 строк из файла
sed -i 1, $(($ (wc -l < путь /to/file ) -10000)) d path/to/file