Veškerá moc příkazové řádky/příkazového řádku přehledně, pro začátečníky i pokročilé
29. Zpracování binárních souborů
Vývoj vanilkové příchuti Linuxu: Knihy kouzel byl 1. března 2025
ukončen. Tento text je zachován jako historický, ale chyby již nejsou
opravovány. Odnože projektu pod kompatibilní licencí jsou vítány.
Tato kapitola uvádí příkazy k analýze, zpracování a úpravě souborů bez jakéhokoliv ohledu
na formát jejich obsahu. Jde o zpracování souboru jako celek, zpracování po jednotlivých bajtech
nebo po blocích pevné velikosti.
Předmětem této kapitoly není šifrování dat, elektronické podepisování, komprese ani ukládání souborů
do archivů či vybalování z nich.
Nástroje od, strings, *sum, split a některé další jsou vyvíjeny v rámci projektu GNU. Nástroj xxd není vyvíjen v rámci projektu GNU.
Velikost-P je počet bajtů, který může obsahovat (a často obsahuje) multiplikativní příponu K, M, G, T, P pro mocniny 1024 (kibibajty, mebibajty atd.) nebo kB, MB, GB, TB, PB (kilobajty, megabajty atd.) pro mocniny 1000. Takže máte-li do příkazu zadat velikost-P , čtyři mebibajty můžete zadat jako „4194304“ nebo jako „4M“ (což je podstatně snazší a přehlednější).
Heš („hash“, „hash code“, někdy méně přesně „kontrolní součet“) je číslo (obvykle v hexadecimálním tvaru) vypočítané z určitých binárních dat pomocí hešovací funkce.
xxd [ -c bajtů-na-řádek ] [ -g bajtů-na-skupinu ] [ -s počáteční-adresa ] [ -l max-počet-bajtů ] [ -u] soubor [ | less]
xxd -b [ -c bajtů-na-řádku ] [ -s počáteční-adresa ] [ -l max-počet-bajtů ] soubor [ | less]
@ najít v binárním souboru čitelné textové řetězce a vypsat je
#3
strings [ -f] [ -n minimální-délka-řetězce ] [ --] soubor
od -A x -t o1z [ -wbajtů-na-řádku ] [ -j počáteční-adresa ] [ -N max-počet-bajtů ] -- [ soubor ] [ | less]
@ vypsat hodnoty bajtů
desítkově #5
od -A x -t u1z [ -wbajtů-na-řádku ] [ -j počáteční-adresa ] [ -N max-počet-bajtů ] -- [ soubor ] [ | less]
@ vypočítat hexidecimální
haše souborů, každou hash na nový řádek (MD5/SHA1/SHA256/SHA512)
#1
md5sum [ --] soubor | sed -E 's/^\\?(\S+)\s.*/\1/'⊨ 8147f2a49ee708d9f7c20164cf48cfcf
sha1sum [ --] soubor | sed -E 's/^\\?(\S+)\s.*/\1/'⊨ c61d1871cf7d71f29e2cfeda9dd73abe18a8fb42
sha256sum [ --] soubor | sed -E 's/^\\?(\S+)\s.*/\1/'
sha512sum [ --] soubor | sed -E 's/^\\?(\S+)\s.*/\1/'
@ vypočítat/ověřit heše (
SHA256 )
#2 (1)
sha256sum soubor > cílový-soubor.sha256
sha256sum [ --ignore-missing] [ --status] -c soubor.sha256
@ vypočítat/ověřit heše (
MD5 )
#3 (2)
md5sum cesta > cílový-soubor.md5
md5sum [ --ignore-missing] [ --status] -c soubor.md5
@ vypočítat kontrolní součet
CRC32 (v hexadecimální soustavě/v desítkové)
#4 (3)
crc32 soubor
printf %d\\n $((0x$(crc32 "soubor ")))
@ vypočítat z jednoho souboru heše (MD5) záznamů ukončených nulovým bajtem
#5
perl -MEnglish -MDigest::MD5 -pe 'BEGIN {$RS = "\x{0}"; $ORS = "\n";} $ARG = Digest::MD5::md5_hex($ARG);' >soubor
@ popsat typ dat souboru (zejména pro člověka)
#1
@ vypsat
MIME typ souboru (vhodné i pro skript)
#2
file [ -b] [ -L] --mime-type soubor
@ určit
velikost souboru v bajtech (alternativy)
#3
wc -c [ soubor ]
stat -c %s soubor
zdroj | wc -c
@ data tvořená
nulovými bajty
#1
head -c velikost-P /dev/zero | zpracování
@ data tvořená
pseudonáhodnými bajty (maximálně 2 147 483 647 bajtů/bez omezení)
#2
openssl rand počet-bajtů | zpracování
while openssl rand 1073741824; do :; done | head -c velikost-P | zpracování
> soubor [ > další-soubor ]
: | zpracování
@ data tvořená bajty konkrétní hodnoty
#4 (4)
head -c velikost-P /dev/zero | tr \\0 $(printf '\\%03o' hodnota-bajtu ) | zpracování
printf %02x {0..255} | xxd -r -p | zpracování
@ příklad: vytvořit soubor o velikosti 2 MiB, tvořený bajty s hodnotu 37 (0x25)
#6
head -c 2M /dev/zero | tr \\0 $(printf '\\%03o' 0x25) | zpracování
@ zkrátit či
prodloužit soubor na uvedenou velikost (obecně/příklady...)
#1 (5)
truncate -s nová-velikost-P soubor
truncate -s 0 soubory/k-vyprazdneni.dat
truncate -s 4M soubory/na-4-mebibajty.dat soubory/dalsi-na-4-mebibajty.dat
@ vytvořit prázdný soubor (vyprázdnit, pokud existuje)(alternativy)
#2
truncate -s 0 [ --] soubor [ další-soubor ]
> soubor [ > další-soubor ]
@ vytvořit soubor tvořený nulovými bajty (alternativy)
#3
truncate -s 0 [ --] soubor && truncate -s velikost-P [ --] soubor
head -c velikost-P /dev/zero >soubor
@ rozdělit soubor na díly po blocích určité velikosti (obecně/příklad)
#2 (7)
split [ --verbose] -b velikost-bloku-P [ -typ-počítadla ] [ -apočet-znaků-počítadla ] [ --additional-suffix="přípona-za-počítadlo "] cesta/k/souboru předpona/cesty/výsledků
split --verbose -b 4M -d -a 5 --additional-suffix=".část" "původní soubor.jpg" ""
@ rozdělit soubor na N přibližně stejně velkých dílů (obecně/příklad)
#3
split [ --verbose] -n počet-dílů [ -typ-počítadla ] [ -apočet-znaků-počítadla ] [ --additional-suffix="přípona-za-počítadlo "] [ -e] cesta/k/souboru předpona/cesty/výsledků
split --verbose -n 7 -d -a 3 --additional-suffix=".část" "původní soubor.jpg" "část-"
@ jsou dva soubory po bajtech
shodné ?
#1
@ jsou po bajtech shodné zadané úseky?
#2
cmp [ -s] -n bajtů-k-porovnání-P soubor1 soubor2 začátek1-P začátek2-P
@ který ze dvou souborů je
větší ?
#3 (8)
test $(stat -c %s "soubor1 ") -gt $(stat -c %s "soubor2 ")
@ grafické rozhraní (GUI)
#1 (9)
@ textové rozhraní (TUI)
#2
hexcurse [ -r bajtů-na-řádku ] soubor
@ obrátit po bajtech celý soubor
#1 (10)
perl -MEnglish -0777 -n -e 'print(scalar(reverse($ARG)))' <vstupní-soubor >výstupní-soubor
@ obrátit každou dvojici/čtveřici/osmici bajtů
#2
dd iflag=fullblock,skip_bytes,count_bytes status=none conv=swab [ if=vstupní-soubor ] [ of=výstupní-soubor ]
xxd -e -g 4 [ soubor ] | xxd -r > cíl
xxd -e -g 8 [ soubor ] | xxd -r > cíl
@ zakódovat do/dekódovat z
base64 #1
base64 -w 0 [ soubor ]
base64 -d [ soubor ] | zpracování
@ zakódovat do/dekódovat z
uuencode #2
uuencode /dev/stdout < soubor | sed -n 'x;3,$p'
sed $'1i\\\nbegin 644 /dev/stdout\n$a\\\nend' temp.dat | uudecode > cíl
@ symetrické kódování operátorem „xor“
#3
rdiff -- signature původní-soubor - | rdiff [ -s] -- delta - nový-soubor - | gzip -9 >cíl-záplata.gz
zcat záplata.gz | rdiff [ -s] -- patch původní-soubor - - >cíl-soubor
@ vzít prvních N bajtů/kibibajtů/mebibajtů/gibibajtů
#1
head -c N soubor
head -c N K soubor
head -c N M soubor
head -c N G soubor
@ vzít prvních N bajtů/kilobajtů/megabajtů/gigabajtů
#2
head -c N soubor
head -c N kB soubor
head -c N MB soubor
head -c N GB soubor
@ vynechat prvních N bajtů/kibibajtů/mebibajtů/gibibajtů
#3
zdroj | dd iflag=fullblock,skip_bytes,count_bytes status=none skip=N | zpracování
zdroj | dd iflag=fullblock,skip_bytes,count_bytes status=none skip=N K | zpracování
zdroj | dd iflag=fullblock,skip_bytes,count_bytes status=none skip=N M | zpracování
zdroj | dd iflag=fullblock,skip_bytes,count_bytes status=none skip=N G | zpracování
@ vynechat prvních N bajtů/kilobajtů/megabajtů/gigabajtů
#4
zdroj | dd iflag=fullblock,skip_bytes,count_bytes status=none skip=N | zpracování
zdroj | dd iflag=fullblock,skip_bytes,count_bytes status=none skip=N kB | zpracování
zdroj | dd iflag=fullblock,skip_bytes,count_bytes status=none skip=N MB | zpracování
zdroj | dd iflag=fullblock,skip_bytes,count_bytes status=none skip=N GB | zpracování
@ příklad: vzít třetí mebibajt souboru
#5
dd iflag=fullblock,skip_bytes,count_bytes status=none skip=2M count=1M <soubor.dat
@ příklad: vynechat třetí mebibajt souboru
#6
(dd iflag=fullblock,skip_bytes,count_bytes status=none count=2M && dd iflag=fullblock,skip_bytes,count_bytes status=none count=1M of=/dev/null && cat) <soubor.dat
@ určit počet bajtů určité hodnoty v daném souboru (obecně/určit počet bajtů 0xa9)
#1
tr -cd \\$(printf %o hodnota-bajtu ) <soubor | wc -c
tr -cd \\$(printf %o 0xa9) <soubor | wc -c
Poznámka: Následující zaklínadla generují/přijímají jednu číselnou hodnotu na každou řádku.
@ bajty
hexadecimálně „00“ až „FF“ (na čísla/z čísel)
#1
zdroj | xxd -p -u -c 1 | zpracování
zdroj | xxd -r -p | zpracování
@ bajty
desítkově „0“ až „255“ (na čísla/z čísel)
#2
zdroj | od -A n -t u1 -v -w1 | tr -d " " | zpracování
zdroj | sed $'1i\\\nobase=16' | bc | sed -E 's/^.$/0&/' | xxd -r -p | zpracování
@ bajty
binárně „00000000“ až „11111111“ (na čísla/z čísel)
#3
zdroj | xxd -b -c 1 | cut -d " " -f 2 | zpracování
zdroj | sed $'1i\\\nobase=16\\\nibase=2' | bc | sed -E 's/^.$/0&/' | xxd -r -p | zpracování
@ bajty
osmičkově „000“ až „377“ (na čísla/z čísel)
#4
zdroj | od -A n -t o1 -v -w1 | tr -d " " | zpracování
zdroj | sed $'1i\\\nobase=16\\\nibase=8' | bc | sed -E 's/^.$/0&/' | xxd -r -p | zpracování
@ nastavit
bajt na určité adrese
#1 (11)
printf '%08x:%02x\n' adresa hodnota-bajtu [ další-adresa hodnota-bajtu ] | xxd -r -c 1 - soubor
@ přepsat úsek bajtů v souboru
#2 (12)
zdroj | dd iflag=fullblock,skip_bytes,count_bytes [ status=progress] conv=nocreat,notrunc [ oflag=seek_bytes seek=kam-zapsat ] of=soubor-k-zápisu
@ vypustit bajty uvedených hodnot/všechny kromě bajtů uvedených hodnot
#3
zdroj | tr $(printf -d '\\%03o' bajt ) | zpracování
zdroj | tr $(printf -cd '\\%03o' bajt ) | zpracování
@ tabulkový překlad bajtů
#4 (13)
zdroj | tr $(printf '\\%03o' původní-bajt ) $(printf '\\%03o' náhradní-bajt ) | zpracování
@ příklad: nahradit v souboru a.bin bajty 0x0a hodnotou 0x0c a výsledek zapsat do b.bin
#5
tr $(printf '\\%03o' 0x0a) $(printf '\\%03o' 0x0c) <a.bin >b.bin
@ vynechat úsek mezi dvěma adresami
#6
@ nahradit úsek mezi dvěma adresami vstupem
#7
@ vložit nový úsek dat na zadanou adresu (obecně/příklad)
#8
zdroj-nového-úseku | cat <(head -c adresa-desítkově [ --] soubor ) - <(tail -c +$((adresa-desítkově +1)) [ --] soubor ) | zpracování
cat novy-usek.dat | cat <(head -c 21734 puvodni.dat) - <(tail -c +$((21734+1)) puvodni.dat) >novy-soubor.dat
Důležitý tip: v každém příkazu, kde je „| zpracování “, můžete místo něj uvést přesměrování do souboru.
split -typ-dělení -typ-počítadla [ -další -parametry ] vstupní-soubor předpona/výstupu
Typ dělení může být:
-b velikost-P :: dělení na bloky pevné velikosti
-C velikost-P :: dělení po záznamech; do každého dílu zapíše jen tolik záznamů, aby nepřekročil uvedenou velikost // [ ] vyzkoušet!
-l počet-záznamů :: dělení po záznamech; do každého dílu zapíše pevný počet záznamů (poslední díl jich může obsahovat méně) // [ ] vyzkoušet!
-n počet-výstupních-souborů :: pokusí se rozdělit vstup na daný počet přibližně stejně velkých souborů.
Při dělení po záznamech je možno uvést parametr -t, který specifikuje ukončovač záznamů; např.:
-t \\0 :: nulový bajt
-t $'\t' :: tabulátor
-t $'\n' :: konec řádky (výchozí hodnota)
-t $'\xa0' :: bajt o hodnotě 0xa0
Typ počítadla může být:
(neuvedený) :: použijí se malá písmena anglické abecedy (aa, ab, ac, ...)
-d :: použijí se desítkové číslice (00, 01, 02, ...)
-x :: použijí se šestnáctkové číslice (00, 01, ..., 09, 0a, 0b, 0c, 0d, 0e, 0f, 10, ...)
--numeric-suffixes=hodnota :: použijí se desítkové číslice počínaje uvedenou hodnotou (např. 12, 13, ...)
Další parametry mohou být:
-ačíslo :: počet „číslic“ počítadla (výchozí hodnota: 2)
--additional-suffix=řetězec :: řetězec k připojení za počítadlo (Poznámka: nesmí obsahovat „/“.) Výchozí hodnotou je prázdný řetězec.
--verbose :: oznámí vytvoření každého výstupního souboru
Tip: Místo vstupního souboru může být „-“; příkaz pak čte ze standardního vstupu.
xxd [ parametry ] vstupní-soubor
zdroj | xxd -r [ parametry ] - soubor-k-přepsání
zdroj | xxd -r [ parametry ] - | zpracování
-p použije „holý“ hexadecimální formát bez adres (výchozí chování: čitelný formát s adresami)
-u v hexadecimálních číslech použije velká písmena (výchozí chování: malá písmena)
-c bajtů počet bajtů na řádek výstupu
-s adresa začne vypisovat od zadané adresy (např. „0x80“)
-l počet-bajtů vypíše nejvýše zadaný počet bajtů
zdroj | xxd -r [ parametry ] | zpracování
zdroj | xxd -r [ parametry ] - soubor-k-editaci
-c bajtů počet bajtů na řádku vstupu (nemá smysl v kombinaci s parametrem „-p“)
-p očekává „holý“ hexadecimální formát bez adres; bílé znaky jsou ignorovány
-seek posun před každým zápisem k adrese přičte uvedený posun (např „0x80“)
@ rdiff, xxd, ghex, hexcurse
#1
sudo apt-get install rdiff xxd ghex hexcurse
sudo apt-get install libarchive-zip-perl
sudo apt-get install sharutils
Ostatní použité příkazy jsou přítomny i v minimální instalaci Ubuntu.
Příkaz „cmp“ je nejrychleji čtoucí příkaz, který znám, lze jej použít např. pro výkonnostní test SSD disku.
V této verzi kapitoly chybí:
Tato kapitola záměrně nepokrývá:
1 Analogicky můžete také použít příkazy „sha1sum“, „sha224sum“, „sha384sum“ a „sha512sum“. Existuje také obecný „shasum“.
2 Heše souborů a jejich názvy (včetně cesty) se uloží do uvedeného souboru.
3 Poznámka: Příkaz „crc32“ lze použít i s více soubory, ale v takovém případě vypisuje ke kontrolním součtům i názvy souborů bez odzvláštnění, což znamená, že nelze bezpečně zpracovat soubory jejichž cesta obsahuje znak konce řádky.
4 Hodnotu bajtu můžete zadat dekadicky (např. „127“), hexadecimálně (např. „0x7f“) nebo osmičkově (např. „0177“).
5 Prodlužuje se vždy nulovými bajty, zkracuje se zprava (tzn. od konce). Pokud soubor neexistuje, vytvoří se.
6 Tip: mezi soubory můžete vložit data ze standardního vstupu zadáním parametru minus („-“) místo jednoho souboru.
7 Pro „-typ-počítadla“ viz popis příkazu „split“ v sekci Parametry příkazů. Pro kontrolu vřele doporučuji použít parametr „--verbose“.
8 Pokud příkaz uspěje, „soubor1“ je větší; jinak je nutno soubory otestovat ještě v opačném pořadí; pokud obě testování selžou, jsou soubory stejně velké.
9 Když otevřete nové okno příkazem „View“/„Add View“, nové okno nebude mít sloupec s adresami, bez něhož je obtížně použitelné. Vyřešit se to dá tak, že zvolíte „Edit“/„Preferences“ a na kartě „Editing“ odškrtnete a zaškrtnete pole „Show offset columns“; pak se sloupec s adresami zobrazí ve všech oknech editoru.
10 Při obracení velkých souborů se ujistěte, že se do paměti RAM a odkládacího souboru vejde dvojnásobek celého souboru! To znamená, že např. pro obrácení souboru o velikosti 4 GiB potřebujete 8 GiB prostoru.
11 Adresy nemusejí být v pořadí, dokonce se mohou opakovat; xxd zapíše jeden bajt po druhém.
12 Hodnota „kam-zapsat“ je obyčejné desítkový index počátečního bajtu, počítáno od nuly. Zápis může pokračovat za stávající konec souboru, ale pokud bude cílová adresa ležet za koncem souboru, zápis začne bezprostředně za poslední existující bajt.
13 Počet „původních bajtů“ musí přesně odpovídat počtu náhradních bajtů, jinak výsledek nemusí odpovídat očekávání.
🗐 Přehled kapitol