BBE(1)

πŸ“¦
version 0.2.2 Β· 2 versions
, in debian bookworm, debian trixie, ubuntu jammy, ubuntu noble, ubuntu questing, ubuntu resolute, ubuntu stonking

πŸ’– BBE(1) β€” bestie edition πŸ’–

okay so. sit down. hydrate. because I am about to put you on to bbe, aka the binary block editor, and it is genuinely one of my favorite little gremlins in the whole toolbox. no cap.


✨ NAME ✨

bbe β€” it's a binary block editor, and it's about to be your new hyperfixation πŸ¦‹


🌸 SYNOPSIS 🌸

bbe [options]...

that's it. that's the whole vibe. options go in, magic comes out πŸ’…


πŸŽ€ DESCRIPTION πŸŽ€

so like. imagine sed, right? but for binary files. that's bbe. she does binary transformations on the blocks of an input stream, and she does it flawlessly. it's giving "I'm not like other editors." πŸ”₯


πŸ‘‘ OPTIONS πŸ‘‘

bbe accepts the following options, and yes, we're going through all of them, bestie, no skipping:

  • -b, --block=BLOCK β€” the block definition. we'll get into what BLOCK can be in a sec, hold on 🫢
  • -e, --expression=COMMAND β€” adds COMMAND to the pile of commands that are gonna get executed ✨
  • -f, --file=script-file β€” takes the contents of script-file and adds them to your commands πŸ“œ
  • -o, --output=name β€” write the output to name instead of just yeeting it to standard output πŸ’Œ
  • -s, --suppress β€” suppress the normal output, and only print the block contents. quiet queen behavior 🀫
  • -?, --help β€” lists literally every available option and what it means. your cheat sheet fr πŸ“‹
  • -V, --version β€” shows the version of the program ⭐

🌈 BLOCK, explained 🌈

BLOCK can be defined as any of these, and this is the part where it gets so good:

  • N:M β€” the N'th byte starts a block that's M bytes long. and yes, the first byte is 0, we count from zero here πŸ’€
  • :M β€” block length in the input stream is M
  • /start/:M β€” the string start starts the block, and the block is M bytes long
  • /start/:/stop/ β€” the string start starts the block, and the block ends at the string stop
  • /start/: β€” the string start starts the block, and the block ends at the next occurrence of start. and important: only the first start is included in the block 🫣
  • :/stop/ β€” the block starts at the beginning of the input stream (or at the end of the previous block) and ends at the next occurrence of stop. the string stop will be included in the block

special value $ for M means the end of stream 🌊

default value for block is 0:$, meaning the whole input stream. yes, everything. the whole thing. main character energy πŸ‘‘


🧚 escaping, because binary is messy 🧚

both start and stop strings are included in the block. nonprintable characters can be escaped like this:

  • \nnn β€” decimal
  • \xnn β€” hexadecimal
  • \0nnn β€” octal

the character \ can be escaped as \\. and these escape codes also work: \a, \b, \t, \n, \v, \f, \r and \; ✨

length (N and M) can be defined as a decimal (n), a hexadecimal (xn) or an octal (0n) value. iykyk πŸ’œ


πŸ’… COMMAND SYNOPSIS πŸ’…

bbe has two types of commands: block commands and byte commands, and both are always related to the current block. which means β€” and this is the important bit β€” the input stream outside of the blocks stays untouched. we don't touch what isn't ours, periodt πŸ™…


πŸ“ Block commands πŸ“

  • D [n] β€” deletes the n'th block. without n, all found blocks are deleted from the output stream πŸ’€
  • I string β€” inserts the string string before the block
  • A string β€” appends the string string at the end of the block
  • J n β€” skips n blocks before executing the commands after this command
  • L n β€” leaves all blocks unmodified starting from block number n. only affects the commands that come after this command ⚠️
  • N β€” before printing a block, the file name in which the block starts is printed
  • F f β€” before printing a block, the input stream offset at the beginning of the block is printed. f can be H, D or O for Hexadecimal, Decimal or Octal format of the offset
  • B f β€” before printing a block, the block number is printed (first block == 1). f can be H, D or O for Hexadecimal, Decimal or Octal format of the block number
  • > file β€” before printing a block, the contents of the file file are printed
  • < file β€” after printing a block, the contents of the file file are printed

πŸ¦‹ Byte commands πŸ¦‹

quick note bestie: n in byte commands is the offset from the beginning of the current block, and it starts from zero. always zero. we love zero 🫢

  • r n string β€” replaces bytes starting at position n with the string string
  • i n string β€” inserts string starting at position n
  • p format β€” the contents of the block are printed in the format defined by format. format can be any of H, D, O, A and B for Hexadecimal, Decimal, Octal, Ascii and Binary 🌈
  • s/search/replace/ β€” replaces all occurrences of search with replace
  • y/source/dest/ β€” translates bytes in source to the corresponding bytes in dest. source and dest must be the same length ⚠️
  • d n m|* β€” deletes m bytes starting from the offset n. if * is defined instead of m, then all bytes starting from n are deleted
  • c from to β€” converts bytes from format from to to. currently supported formats are:
    • BCD β€” Binary coded decimal
    • ASC β€” Ascii
  • j n β€” commands after the j-command are ignored for the first n bytes of the block
  • l n β€” commands after the l-command are ignored from the n'th byte of the block
  • w file β€” writes bytes from the current block to the file file. the commands before the w-command decide what will be written. %B or %nB in file will be replaced by the current block number. n in %nB is the field length, and a leading zero in n causes the block number to be left padded with zeroes πŸŽ€
  • & c β€” performs binary and with c
  • | c β€” performs binary or with c
  • ^ c β€” performs binary xor with c
  • ~ β€” performs binary negation
  • u n c β€” all bytes from the start of the block to offset n are replaced by c
  • f n c β€” all bytes starting from offset n to the end of the block are replaced by c
  • x β€” exchanges the contents of the nibbles (half an octet) of the bytes

nonvisible characters in strings can be escaped the same way as in block definition strings. and fun fact: the character / in the s and y commands can be any visible character ✨

⚠️ heads up bestie, this one matters: note that the D, A, I, F, B, c, s, i, y, p, <, > and d commands cause the length of the input and output streams to be different. so like. plan accordingly πŸ’€

🌟 EXAMPLES 🌟

because seeing it is believing, here's the girlies in action:

bbe -e "s/c:\\temp\\data1.txt/c:\\temp\\data2.txt/" file1

all occurrences of c:\temp\data1.txt in the file file1 are changed to c:\temp\data2.txt πŸ’«

bbe -b 0420:16 -e "r 4 \x12\x4a" file1

two bytes starting at the fifth byte of a 16 byte long block starting at offset 0420 (octal) in file1 are changed to hexadecimal values 12 and 4a πŸ”₯

bbe -b :16 -e "A \x0a" file1

a newline is added after every block, and the block length is 16 🌸


πŸ‘€ SEE ALSO πŸ‘€

sed(1). yeah, that sed. the one you already know and love. go say hi 🫢


πŸ’œ AUTHOR πŸ’œ

Timo Savinen <tjsa@iki.fi > β€” iconic behavior, honestly. thank you for our lives πŸ‘‘


and that's the whole page bestie!! πŸŽ€ this one's dated 2006-11-02 and it's page BBE(1) of the manual β€” go forth, edit some binary, and slay πŸ’–βœ¨πŸ¦‹