#(bytes) $ 
cat test.bin | hexdump -ve '/1 "%02x"' ### обратная функция: cat hexstring.txt | xxd -r -p > output.bin

#(words) $ 
cat test.bin | hexdump -ve '/2 "%04x"'

---------
Символы формата:

/1 — говорит, что читать и форматировать следует по одному байту,

/2 — по два байта как единое целое,

"%02x" — формат вывода одного байта с лидирующими нулями,

"%04x" — формат вывода двухбайтового слова с лидирующими нулями.

Таким образом, первый пример выводит dump построчно байт за байтом, а второй — группами из двух байт (в том числе меняя порядок байтов на little-endian, если используется hexdump по умолчанию).

Если нужно корректно читать слова в вашем файле как они идут (big-endian или little-endian), нужно знать порядок байтов в данных. Но с точки зрения формата вывода /1 "%02x" — байт за байтом, /2 "%04x" — слова по 2 байта как слово.

Это стандартное поведение команды hexdump с параметром формата вывода.

** или ***
$ cat hexbin.c

/*
 * hexbin.c — самодостаточная замена связки
 *   cat file.bin | hexdump -ve '/1 "%02x"'      (кодирование bin -> hex)
 *   cat hex.txt  | xxd -r -p > file.bin          (декодирование hex -> bin)
 *
 * Использование:
 *   hexbin -e < input.bin  > hex.txt     кодирование (bin -> сплошной hex, lowercase)
 *   hexbin -d < hex.txt    > output.bin  декодирование (hex -> bin)
 *
 * Компиляция для полной автономности (статический бинарник, без внешних
 * зависимостей — можно скопировать на любой linux x86_64 и запустить):
 *
 *   gcc -O2 -Wall -Wextra -static -o hexbin hexbin.c
 *
 * Если статическая линковка недоступна (нет libc.a), собрать динамически:
 *   gcc -O2 -Wall -Wextra -o hexbin hexbin.c
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define BUF_SIZE 65536

static const char HEX[] = "0123456789abcdef";

/* bin -> hex (аналог hexdump -ve '/1 "%02x"') */
static int encode(void)
{
    unsigned char in[BUF_SIZE];
    char out[BUF_SIZE * 2];
    size_t n;

    while ((n = fread(in, 1, sizeof(in), stdin)) > 0) {
        for (size_t i = 0; i < n; i++) {
            out[i * 2]     = HEX[(in[i] >> 4) & 0xF];
            out[i * 2 + 1] = HEX[in[i] & 0xF];
        }
        if (fwrite(out, 1, n * 2, stdout) != n * 2) {
            perror("fwrite");
            return 1;
        }
    }
    if (ferror(stdin)) {
        perror("fread");
        return 1;
    }
    return 0;
}

static int hexval(int c)
{
    if (c >= '0' && c <= '9') return c - '0';
    if (c >= 'a' && c <= 'f') return c - 'a' + 10;
    if (c >= 'A' && c <= 'F') return c - 'A' + 10;
    return -1;
}

/* hex -> bin (аналог xxd -r -p), пробелы/переводы строк игнорируются */
static int decode(void)
{
    int c;
    int have_high = 0;
    int high = 0;
    long pos = 0;

    while ((c = getchar()) != EOF) {
        if (c == ' ' || c == '\t' || c == '\r' || c == '\n')
            continue;

        int v = hexval(c);
        if (v < 0) {
            fprintf(stderr, "hexbin: недопустимый символ hex '%c' на позиции %ld\n", c, pos);
            return 1;
        }
        pos++;

        if (!have_high) {
            high = v;
            have_high = 1;
        } else {
            unsigned char byte = (unsigned char)((high << 4) | v);
            if (putchar(byte) == EOF) {
                perror("putchar");
                return 1;
            }
            have_high = 0;
        }
    }

    if (have_high) {
        fprintf(stderr, "hexbin: нечётное количество hex-символов (незавершённая пара)\n");
        return 1;
    }
    return 0;
}

static void usage(const char *prog)
{
    fprintf(stderr,
        "Использование: %s -e|-d\n"
        "  -e   кодировать stdin (бинарные данные) в hex-строку -> stdout\n"
        "  -d   декодировать stdin (hex-строку) в бинарные данные -> stdout\n",
        prog);
}

int main(int argc, char **argv)
{
    if (argc != 2) {
        usage(argv[0]);
        return 2;
    }

    if (strcmp(argv[1], "-e") == 0 || strcmp(argv[1], "--encode") == 0)
        return encode();

    if (strcmp(argv[1], "-d") == 0 || strcmp(argv[1], "--decode") == 0)
        return decode();

    usage(argv[0]);
    return 2;
}