2013-08-06 1 views
13

Я имею в виду How can you concatenate two huge files with very little spare disk space?Усечения первого 100Мба файла в Linux

Я нахожусь в разгаре осуществления следующих действий:

  1. Выделяет разреженный файл комбинированного размера.
  2. Скопируйте 100Mb из конца второго файла в конец нового файла.
  3. Усечение 100Mb конца второго файла
  4. Loop 2 & 3 до завершения второго файла (с 2. измененным до нужного места в целевом файле).
  5. Do 2 4 но с первым файлом.

Я хотел бы знать, есть ли там кто-нибудь, кто может «обрезать» данный файл в Linux? Усечение осуществляется по размеру файла, например, если файл равен 10 ГБ, я бы хотел усечь первый 100 МБ файла и оставить файл с оставшимся 9,9 ГБ. Кто-нибудь может помочь в этом?

Thanks

+0

Вы использовали Google для 'Linux file truncate'? Это даст вам хорошие ответы! –

+0

Возможный дубликат [Truncate file at front] (http://stackoverflow.com/questions/706167/truncate-file-at-front) –

ответ

2

Пожалуйста, прочитайте хорошую книгу программирования Linux, например. Advanced Linux Programming.

Вы должны использовать Linux kernelsyscalls см syscalls(2)

В частности truncate(2) (как для усечения, так и для расширения разреженного файла на файловых системах, поддерживающих его), и stat(2) в частности, получить размер файла.

Существует нет (переносимый или файловой системы) способ удаления байтов с начала (или в середине) файла, вы можете обрезать файл только в конце.

+0

Да, это именно то, что моя проблема. Во всяком случае, насколько я знаю, обрезать в linux только усекать до фиксированного размера файла. например, если вы хотите, чтобы ваш размер файла составлял 4 КБ, вы просто делаете 'truncate -s 4k filename.txt'. Я хочу, чтобы мой файл уменьшал либо голову, либо хвост на 100 МБ. Это достижимо? – CheeHow

5

Отказ от начала файла в большинстве файловых систем невозможен, и для этого нет общего API; например, функция truncate только модифицирует окончание файла.

Возможно, вы сможете сделать это с некоторыми файловыми системами. Например, файловая система ext4 недавно получил IOCTL, что могут оказаться полезными: http://lwn.net/Articles/556136/

+0

ОП упоминает усечение * в конце файла * в теле вопроса –

+0

Да, а также начало. – Joni

+0

Несмотря на то, что нет четкого решения, мне сейчас нужно только использовать команду «truncate», чтобы вручную усечь хвост файла, получив размер вычитаемого файла на 100 МБ. Спасибо за предложение, хотя ... – CheeHow

13

ответа, то теперь это реальность с ядром 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); 
} 
1

Если вы можете работать с ASCII-строками, а не байтами, то удалить первые n строк файла легко. Например, чтобы удалить первые 100 строк:

sed -i 1,100d /path/to/file 
+1

линии отличаются от размера. – user2284570

0

Это довольно старый вопрос, но вот мой подход к нему.За исключением требования для того, чтобы быть сделано с ограниченным пространством доступны, я хотел бы использовать что-то похожее на следующее укоротить первый 100mb файла:

$ tail --bytes=$(expr $(wc -c < logfile.log) - 104857600) logfile.log > logfile.log.tmp 
$ mv logfile.log.tmp logfile.log 

Объяснение:

  • Это выводит последний пп байтов файла (tail -bytes).
  • Число байтов в файле для вывода вычисляется как размер файла (wc -c < logfile.log) минус 100 Мб (expr $ (...) - 104857600). Это оставило бы нас с 100 Мб меньше размера файла, чтобы взять хвост (например, 9.9Gb)
  • Затем он выводится в файл temp, а затем возвращается к исходному имени файла, чтобы оставить усеченный файл.
-1

удалить все, кроме последних 10000 строк из файла

СЭД -i 1, $ (($ (туалет -l < путь/к/файлу) -10000)) d путь/к/файлу

+0

вопрос был основан на размере файла, а не количестве строк –

Смежные вопросы