2013-08-06 13 views
13

Mam na myśli How can you concatenate two huge files with very little spare disk space?Obcinanie pierwszy 100MB pliku w linux

jestem pośród realizacji następujących czynności:

  1. Przeznaczyć rzadki plik o łącznej wielkości.
  2. Skopiuj 100Mb z końca drugiego pliku na koniec nowego pliku.
  3. Skróć 100Mb końca drugiego pliku
  4. Pętla 2 & 3 aż zakończysz drugi plik (z 2. zmodyfikowany do poprawnego miejsca w pliku docelowym).
  5. Do 2 4 ale z pierwszym plikiem.

Chciałbym wiedzieć, czy jest tam ktoś, kto jest w stanie "skrócić" dany plik w Linuksie? Obcinanie odbywa się według rozmiaru pliku, na przykład, jeśli plik ma 10 GB, chciałbym skrócić pierwsze 100 MB pliku i pozostawić plik z pozostałymi 9,9 GB. Czy ktoś może w tym pomóc?

Dzięki

+0

Czy szukałeś google w celu "skracania pliku Linux"? Dałoby ci to dobre odpowiedzi! –

+0

możliwy duplikat [Truncate file at front] (http://stackoverflow.com/questions/706167/truncate-file-at-front) –

Odpowiedz

2

Proszę przeczytać dobrą książkę do programowania Linuksa, np. Advanced Linux Programming.

Trzeba użyć Linux kernelsyscalls patrz syscalls(2)

W szczególności truncate(2) (zarówno do obcinania i rozszerzenia pliku rzadki w systemach plików wspierających go), a zwłaszcza stat(2) aby uzyskać rozmiar pliku.

Nie ma (przenośnego lub neutralnego systemu plików) sposobu na usunięcie bajtów od początku (lub w środku) pliku, można przyciąć plik tylko na jego końcu.

+0

tak, to jest dokładnie to, co jest moim problemem. W każdym razie, o ile mi wiadomo, truncate w Linuksie tylko obcina do stałego rozmiaru pliku. na przykład jeśli chcesz mieć rozmiar pliku 4KB, po prostu wykonaj 'truncate -s 4k filename.txt'. Chcę, aby mój plik zmniejszył jego głowę lub ogon o 100 MB. Czy to jest osiągalne? – CheeHow

5

Przycinanie początku pliku nie jest możliwe w przypadku większości systemów plików i nie ma w tym celu żadnego ogólnego interfejsu API; na przykład funkcja obcięcia tylko modyfikuje zakończenie pliku.

Możliwe, że można to zrobić w niektórych systemach plików. Na przykład system plików ext4 niedawno dostał ioctl, które mogą okazać się przydatne: http://lwn.net/Articles/556136/

+0

OP wspomina o skracaniu * na końcu pliku * w treści pytania –

+0

Tak, a także na początku. – Joni

+0

chociaż nie ma jednoznacznego rozwiązania, teraz moim celem jest użycie polecenia 'truncate' w celu ręcznego obcinania ogona poprzez odjęcie rozmiaru pliku o 100 MB. Dzięki za sugestię ... – CheeHow

13

Odbierz teraz jest to rzeczywistość z Linux v3.15 jądra (ext4/XFS)

przeczytać tutaj http://man7.org/linux/man-pages/man2/fallocate.2.html

Kod testowy

#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

Jeśli możesz pracować z wierszami ASCII, a nie bajtami, usunięcie pierwszych n wierszy pliku jest łatwe. Na przykład, aby usunąć pierwsze 100 wierszy:

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

linie różnią się od rozmiaru. – user2284570

0

To już dość stare pytanie, ale oto moje zdanie na ten temat.Z wyjątkiem wymogu, aby można zrobić z ograniczoną przestrzeń dostępna, chciałbym użyć czegoś podobnego do następującego obciąć pierwszy 100MB plik:

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

Objaśnienie:

  • Ten wysyła ostatni nn bajty pliku (tail --bytes).
  • Liczba bajtów w pliku do wyprowadzenia jest obliczana jako rozmiar pliku (wc -c < logfile.log) minus 100 MB (wyraż. $ (...) - 104857600). To zostawiłoby nas o 100Mb mniej niż rozmiar pliku do pobrania ogona (np. 9,9 Gb).
  • To jest następnie wyprowadzane do pliku tymczasowego, a następnie przenoszone z powrotem do oryginalnej nazwy pliku, aby pozostawić obcięty plik.
-1

Usunąć wszystkie, oprócz ostatnich 10000 wierszy z pliku

sed -i 1, $ (($ (wc -l < ścieżka/do/pliku) -10.000)) d ścieżka/do/pliku

+0

pytanie zostało oparte na rozmiarze pliku, a nie na ilości linii –

Powiązane problemy