Użyj `dd`, aby wyciąć końcową część pliku

18

Prawdopodobnie jest to prosta sztuczka, ale nie mogę tego zrozumieć na stronie podręcznika.

Jak wyciąć na przykład ostatnie 1 MB z pliku o nieokreślonym rozmiarze, używając dd?

zetah
źródło
1
Chcesz kopię tego pliku, z wyjątkiem ostatniego 1 MB, czy chcesz, aby ostatni MB został skopiowany do innego pliku?
Mat
Chcę ostatni 1 MB
zetah

Odpowiedzi:

29

Cóż, zakładając, że masz stati bashmożesz uzyskać rozmiar pliku za pomocą:

stat -c %s your_file

Jeśli chcesz wyodrębnić ostatnie $amountbajty dla tego pliku dd, możesz:

dd if=your_file of=extracted_part \
   bs=1 count=$amount \
   skip=$(( $(stat -c %s your_file) - $amount ))

Ale rozsądniejszym podejściem byłoby użycie tail:

tail -c $(( 1024*1024 )) your_file > target_file
Mata
źródło
Brak -copcji dla head?
ADTC
Myślę, że miał na myśli + $ ((1024 * 1024)): -c, --bytes = K wypisuje ostatnie K bajtów; alternatywnie użyj -c + K, aby wyprowadzić bajty zaczynające się od Kth każdego pliku
Vanuan
5
dd --help
Zastosowanie: dd [OPERAND] ...
  lub: dd OPCJA
Skopiuj plik, konwertując i formatując zgodnie z operandami.

  bs = BYTES odczytuje i zapisuje bajty BYTES jednocześnie (patrz także ibs =, obs =)
  cbs = BYTES konwertuje bajty BYTES na raz
  conv = CONVS przekonwertuj plik zgodnie z listą symboli oddzielonych przecinkami
  count = BLOCKS kopiuj tylko bloki wejściowe BLOCKS
  ibs = BYTES odczytuj bajty BYTES na raz (domyślnie: 512)
  if = PLIK odczytany z PLIKU zamiast standardowego wejścia
  iflag = FLAGI czytane zgodnie z listą symboli oddzielonych przecinkami
  obs = BYTES zapisuj bajty BYTES na raz (domyślnie: 512)
  of = PLIK zapisuje do PLIKU zamiast standardowego wyjścia
  oflag = FLAGI zapisuj zgodnie z listą symboli oddzielonych przecinkami
  seek = BLOCKI pomiń BLOCKS obs-size bloki na początku wyjścia
  pomiń = BLOKI pomiń BLOKI bloki wielkości ibs na początku wprowadzania
  status = noxfer pomija statystyki transferu

BLOKI i BYTES mogą być poprzedzone następującymi multiplikatywnymi sufiksami:
c = 1, w = 2, b = 512, kB = 1000, K = 1024, MB = 1000 * 1000, M = 1024 * 1024, xM = M
GB = 1000 * 1000 * 1000, G = 1024 * 1024 * 1024 itd. Dla T, P, E, Z, Y.

Jeśli rozmiar pliku to dokładnie 10 MB, 1024 * 10 10240 K To pozostawi ostatnie 1024 KB. Powinieneś określić rozmiar bloku, z którym pracujesz, używając opcji ibs i obs.

1M = 1024K 
1024*9 = 9216  
dd if=/10/MB/file of=/9/MB/file count=9216K ibs=1K obs=1K
dd if=/10/MB/file of=/9/MB/file count=9M ibs=1M obs=1M

Możesz także pominąć pierwszy 1 MB pliku, używając opcji pomijania, aby przeczytać do końca pliku, pomijając pierwszy 1 MB.

dd if=/10/MB/file of=/9/MB/file skip=1M ibs=1M obs=1M

Korzystając z opcji wyszukiwania, możesz napisać a do określonego miejsca w pliku wyjściowym. Powiedz, że chcesz zachować pierwszy 1 MB, a później zapisać ostatnie 8 MB.

dd if=/10/MB/file of=/9/MB/file skip=1M seek=1M count=8M ibs=1M obs=1M

Prawdopodobnie musisz uzyskać szczegółowe informacje na temat rozmiaru pliku, aby upewnić się, że otrzymujesz odpowiednią ilość danych.

ls -s --block-size 1K ./my/10MB/file
człowiek ls

       --block-size = ROZMIAR
              użyj bloków bajtów SIZE. Zobacz format SIZE poniżej

       -s, --size
              wydrukuj przydzielony rozmiar każdego pliku, w blokach

       ROZMIAR może być (lub może być liczbą całkowitą, opcjonalnie po nim) jednym z następujących
       lowing: KB 1000, K 1024, MB 1000 * 1000, M 1024 * 1024 itd. dla G, T,
       P, E, Z, Y.
nelaaro
źródło