it-swarm.com.ru

Преобразовать строку в шестнадцатеричный в командной строке

Я пытаюсь преобразовать "Hello" в 48 65 6c 6c 6f в шестнадцатеричном как можно более эффективно, используя командную строку.

Я пытался посмотреть на printf и Google, но я никуда не могу добраться.

Любая помощь с благодарностью.

Спасибо заранее,

20
Eamorr
echo -n "Hello" | od -A n -t x1

Объяснение:

  • Программа echo предоставит строку для следующей команды.
  • Флаг -n указывает эхо не генерировать новую строку в конце "Hello".
  • Программа od - это программа "восьмеричный дамп". (Мы предоставим флаг, который скажет, чтобы он сбрасывал его в шестнадцатеричном виде вместо восьмеричного.)
  • Флаг -A n - это сокращение от --address-radix=n, а n - это "нет". Без этой части команда выведет уродливый префикс числового адреса на левой стороне. Это полезно для больших дампов, но для короткой строки это не нужно.
  • Флаг -t x1 является коротким для --format=x1, где x - это "шестнадцатеричный", а 1 означает 1 байт.
42
TMS

Очевидно, @TMS не может RTFM. (см. его комментарии к его предыдущему ответу)

Если вы хотите сделать это и удалить нужные вам пробелы:

echo -n "Hello" | od -A n -t x1 | sed 's/ *//g'

Первые две команды в конвейере хорошо объяснены @TMS в его ответе, отредактированном @James. Последняя команда отличается от комментария @TMS тем, что она верна и проверена. Объяснение:

  • sed - это s tream ed итор.
  • s - это команда s ubstitute.
  • / открывает регулярное выражение - любой символ может быть использован. / является обычным, но неудобным для обработки, скажем, XML или имен путей.
  • / или альтернативный символ, который вы выбрали, закрывает регулярное выражение и открывает строку подстановки.
  • В / */* соответствует любой последовательности предыдущего символа (в данном случае, пробел).
  • / или альтернативный символ, который вы выбрали, закрывает строку замещения. В этом случае строка подстановки // пуста, то есть совпадение удалено.
  • g - это опция для выполнения подстановки g глобально в каждой строке, а не только один раз для каждой строки.
  • Кавычки предотвращают запутывание анализатора команд - вся последовательность передается sed в качестве первой опции, а именно, сценарий sed.

@TMS brain child (sed 's/^ *//') удаляет только пробелы в начале каждой строки (^ соответствует началу строки - 'pattern space' в sed- говорящий).

Если вы дополнительно хотите удалить переводы строки, проще всего добавить

| tr -d '\n'

к командным трубам. Он функционирует следующим образом:

  • | подает ранее обработанный поток на стандартный ввод этой команды.
  • tr - это команда tr anslate.
  • -d указывает на удаление символов совпадения.
  • В кавычках указываются символы совпадения - в данном случае просто новая строка (\n). Перевести соответствует только одиночным символам, а не последовательностям.

sed уникально запаздывает при работе с символами новой строки. Это связано с тем, что sed является одной из самых старых команд unix - она ​​была создана до того, как люди действительно узнали, что они делают. Распространенное устаревшее программное обеспечение защищает его от исправления. Я знаю это, потому что я родился до того, как unix родился.

Историческое происхождение проблемы заключалось в том, что символ новой строки был разделителем строк, а не частью строки. Поэтому он был удален утилитами обработки строк и повторно вставлен утилитами вывода. Проблема в том, что это делает предположения о структуре пользовательских данных и накладывает неестественные ограничения во многих настройках. Неспособность sed легко удалять переводы строк является одним из наиболее распространенных примеров этой искаженной идеологии, вызывающей горе.

Можно удалить переводы строк с помощью sed - просто все решения, которые я знаю о make sed, обрабатывают весь файл одновременно, что приводит к дросселированию очень больших файлов, что отрицательно сказывается на назначении потокового редактора. Любое решение, которое сохраняет обработку строки, если это возможно, было бы нечитаемым крысиным гнездом из нескольких каналов.

Если вы настаиваете на использовании sed, попробуйте:

sed -z 's/\n//g'

-z говорит sed использовать нулевые значения в качестве разделителей строк.

Внутренне строка в C оканчивается нулем. Опция -z также является результатом устаревшей версии, предоставленной для удобства программистов C, которые могут захотеть использовать временный файл, заполненный строками C- и не загроможденный переводами строк. Затем они могут легко читать и обрабатывать по одной строке за раз. Опять же, ранние предположения о вариантах использования накладывают искусственные ограничения на пользовательские данные.

Если вы опустите опцию g, эта команда удалит только первый символ новой строки. С параметром -zsed интерпретирует весь файл как одну строку (если в файл не вставлены случайные нули), завершается нулем, и это также приводит к удушению больших файлов.

Ты можешь подумать

sed 's/^/\x00/' | sed -z 's/\n//' | sed 's/\x00//'

может работать. Первая команда ставит нулевое значение в начале каждой строки построчно, в результате чего \n\x00 заканчивается каждой строкой. Вторая команда удаляет по одной новой строке из каждой строки, теперь разделенной нулями - в силу первой команды будет только одна новая строка. Все, что осталось - это ложные нули. Все идет нормально. Здесь нарушена идея, что канал будет передавать последнюю команду построчно, поскольку именно так был построен поток. На самом деле, последняя команда, как написано, удалит только один ноль, так как теперь весь файл не имеет новых строк и поэтому является одной строкой.

Простая конвейерная реализация использует промежуточный временный файл, и все входные данные обрабатываются и передаются в файл. Следующая команда может выполняться в другом потоке, одновременно читая этот файл, но она просто видит поток целиком (хотя и неполный) и не знает о границах чанка, питающих файл. Даже если канал является буфером памяти, следующая команда видит поток целиком. Дефект неразрывно запекается в sed.

Чтобы этот подход работал, вам нужна опция g в последней команде, так что, опять же, она задыхается от больших файлов.

Суть в следующем: не используйте sed для обработки новых строк.

3
I_always_RTFM_and_STFW

Попробуем поиграть с этим дальше. Рабочим решением является удаление "*", поскольку для первоначального требования нет необходимости просто удалять пробелы, а также, если требуется замена действительного символа, как показано ниже.

echo -n "Hello" | od -A n -t x1 | sed 's/ /%/g'

%48%65%6c%6c%6f

Итак, я рассматриваю это как улучшение, отвечающее первоначальному Q, так как теперь утверждение делает именно то, что требуется, а не только внешне.

1
Tony Su