Dzisiaj musiałem usunąć pierwsze 1131 bajtów z 800 MB mieszanego pliku tekstowego / binarnego, przefiltrowanego zrzutu subwersji, który włamuję do nowego repozytorium. Jak najlepiej to zrobić?
Na początek próbowałem
dd bs=1 skip=1131 if=filtered.dump of=trimmed.dump
ale po pominięciu kopiuje pozostałą część pliku bajt na raz, tj. bardzo powoli. W końcu doszedłem do wniosku, że potrzebowałem 405 bajtów, aby zaokrąglić to do trzech bloków 512, które mogłem pominąć
dd if=/dev/zero of=405zeros bs=1 count=405
cat 405zeros filtered.dump | dd bs=512 skip=3 of=trimmed.dump
które zakończyło się dość szybko, ale musiał istnieć prostszy / lepszy sposób? Czy jest inne narzędzie, o którym zapomniałem? Dzięki!
dd
jest właściwym narzędziem do pracy - wygląda na to, że wymyśliłeś ładne, eleganckie rozwiązanie swojego problemu.Odpowiedzi:
Możesz przełączać opcje bs i pomijać:
W ten sposób operacja może skorzystać z większego bloku.
W przeciwnym razie możesz spróbować z ogonem (chociaż nie jest bezpiecznie używać go z plikami binarnymi):
Na koniec możesz użyć instancji 3 dd, aby napisać coś takiego:
gdzie pierwsze dd wypisuje standardowe wyjście filter.dump; drugi odczytuje tylko 1131 bajtów i wyrzuca je; następnie ostatni odczytuje ze swojego standardowego wejścia pozostałe bajty filter.dump i zapisuje je do trimmed.dump.
źródło
bs=1131 skip=1
: - /Nie jestem pewien, kiedy
skip_bytes
został dodany, ale aby pominąć pierwsze 11 bajtów, masz:Gdzie
iflag=skip_bytes
każe dd interpretować wartośćskip
opcji jako bajty zamiast bloków, co czyni ją prostą.źródło
iflag=skip_bytes skip=1234 bs=1M
Możesz użyć podpowłoki i dwóch
dd
takich wywołań:źródło
Jeśli system plików i jądro Linuksa go obsługują, możesz spróbować
fallocate
wprowadzić zmiany w miejscu: w najlepszym przypadku nie ma żadnych danych we / wy:gdzie
<magic>
zależy od systemu plików, wersji systemu Linux i typu pliku (FALLOC_FL_COLLAPSE_RANGE
lubFALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE
może być używany wewnętrznie ).źródło
Powinieneś użyć
count=0
- to proste,lseek()
gdy tylko jest to możliwe.Lubię to:
dd
wykonalseek()
deskryptor pliku wejściowego z przesunięciem 1131 bajtów, a następniecat
po prostu skopiuje wszystko, co pozostanie na wyjściu.źródło
Jeszcze innym sposobem na usunięcie wiodących bajtów z pliku (bez użycia
dd
w ogóle) jest użyciexxd
ised
lubtail
odpowiednio.źródło
@maxschlepzig prosi o liner online. Oto jeden w perlu. Wymaga 2 argumentów: od bajtu i długości. Plik wejściowy musi być podany jako „<”, a wyjście będzie ustawione na standardowe wyjście:
Jeśli długość jest większa niż plik, reszta pliku zostanie skopiowana.
W moim systemie zapewnia to 3,5 GB / s.
źródło
dd
nie gwarantuje to pełnego odczytu. Spróbuj: tak | dd bs = 1024k liczba = 10 | wc unix.stackexchange.com/questions/17295/…