Linux 在命令行上将字符串转换为十六进制
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6791798/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Convert string to hexadecimal on command line
提问by Eamorr
I'm trying to convert "Hello" to 48 65 6c 6c 6f
in hexadecimal as efficiently as possible using the command line.
我正在尝试48 65 6c 6c 6f
使用命令行尽可能有效地将“Hello”转换为十六进制。
I've tried looking at printf
and google, but I can't get anywhere.
我试过查看printf
和谷歌,但我无处可去。
Any help greatly appreciated.
非常感谢任何帮助。
Many thanks in advance,
提前谢谢了,
采纳答案by TMS
echo -n "Hello" | od -A n -t x1
Explanation:
解释:
- The
echo
program will provide the string to the next command. - The
-n
flag tells echo to not generate a new line at the end of the "Hello". - The
od
program is the "octal dump" program. (We will be providing a flag to tell it to dump it in hexadecimal instead of octal.) - The
-A n
flag is short for--address-radix=n
, with n being short for "none". Without this part, the command would output an ugly numerical address prefix on the left side. This is useful for large dumps, but for a short string it is unnecessary. - The
-t x1
flag is short for--format=x1
, with the x being short for "hexidecimal" and the 1 meaning 1 byte.
- 该
echo
计划将提供该字符串的下一个命令。 - 该
-n
标志告诉 echo 不要在“Hello”的末尾生成新行。 - 该
od
程序是“八进制转储”程序。(我们将提供一个标志,告诉它以十六进制而不是八进制转储它。) - 该
-A n
标志是 的缩写--address-radix=n
,n 是“无”的缩写。如果没有这部分,该命令将在左侧输出一个丑陋的数字地址前缀。这对于大型转储很有用,但对于短字符串则没有必要。 - 该
-t x1
标志是 的缩写--format=x1
,x 是“十六进制”的缩写,1 表示 1 个字节。
回答by I_always_RTFM_and_STFW
If you want to do this and remove the spaces you need:
如果你想这样做并删除你需要的空格:
echo -n "Hello" | od -A n -t x1 | sed 's/ *//g'
The first two commands in the pipeline are well explained by @TMS in his answer, as edited by @James. The last command differs from @TMS comment in that it is both correct and has been tested. The explanation is:
@TMS 在他的回答中很好地解释了管道中的前两个命令,由@James 编辑。最后一条命令与@TMS 注释的不同之处在于它既正确又经过测试。解释是:
sed
is a stream editor.s
is the substitute command./
opens a regular expression - any character may be used./
is conventional, but inconvenient for processing, say, XML or path names./
or the alternate character you chose, closes the regular expression and opens the substitution string.- In
/ */
the*
matches any sequence of the previous character (in this case, a space). /
or the alternate character you chose, closes the substitution string. In this case, the substitution string//
is empty, i.e. the match is deleted.g
is the option to do this substitution globally on each line instead of just once for each line.- The quotes keep the command parser from getting confused - the whole
sequence is passed to
sed
as the first option, namely, ased
script.
sed
是一个小号tream编itor。s
是小号ubstitute命令。/
打开一个正则表达式 - 可以使用任何字符。/
是传统的,但不方便处理,例如 XML 或路径名。/
或您选择的替代字符,关闭正则表达式并打开替换字符串。- 在
/ */
该*
匹配前一字符的任何序列(在此情况下,空间)。 /
或您选择的替代字符,关闭替换字符串。在这种情况下,替换字符串//
为空,即删除匹配项。g
是做这个替代选项摹每行,而不是为每一行lobally只有一次。- 引号可防止命令解析器混淆 - 整个序列
sed
作为第一个选项传递给,即sed
脚本。
@TMS brain child (sed 's/^ *//'
) only strips spaces from the beginning of each line (^
matches the beginning of the line - 'pattern space' in sed
-speak).
@TMS 脑子 ( sed 's/^ *//'
) 只从每行的开头去除空格(^
匹配行的开头 -sed
说话中的“模式空间” )。
If you additionally want to remove newlines, the easiest way is to append
如果您还想删除换行符,最简单的方法是追加
| tr -d '\n'
to the command pipes. It functions as follows:
到命令管道。它的作用如下:
|
feeds the previously processed stream to this command's standard input.tr
is the translate command.-d
specifies deleting the match characters.- Quotes list your match characters - in this case just newline (
\n
). Translate only matches single characters, not sequences.
|
将先前处理的流提供给此命令的标准输入。tr
是TRanslate命令。-d
指定删除匹配字符。- 引号列出您的匹配字符 - 在这种情况下只是换行符 (
\n
)。翻译只匹配单个字符,不匹配序列。
sed
is uniquely retarded when dealing with newlines. This is because sed
is one of the oldest unix
commands - it was created before people really knew what they were doing. Pervasive legacy software keeps it from being fixed. I know this because I was born before unix
was born.
sed
在处理换行符时是独一无二的。这是因为它是sed
最古老的unix
命令之一——它是在人们真正知道他们在做什么之前创建的。普遍存在的遗留软件使其无法修复。我知道这一点,因为我在出生之前unix
就出生了。
The historical origin of the problem was the idea that a newline was a line separator, not part of the line. It was therefore stripped by line processing utilities and reinserted by output utilities. The trouble is, this makes assumptions about the structure of user data and imposes unnatural restrictions in many settings. sed
's inability to easily remove newlines is one of the most common examples of that malformed ideology causing grief.
问题的历史起源是换行符是行分隔符,而不是行的一部分。因此,它被线路处理实用程序剥离并由输出实用程序重新插入。问题是,这对用户数据的结构做出了假设,并在许多设置中施加了不自然的限制。 sed
无法轻松删除换行符是导致悲伤的畸形意识形态的最常见例子之一。
It is possible to remove newlines with sed
- it is just that all solutions I know about make sed
process the whole file at once, which chokes for very large files, defeating the purpose of a stream editor. Any solution that retains line processing, if it is possible, would be an unreadable rat's nest of multiple pipes.
可以删除换行符sed
- 只是我所知道的所有解决方案都会同时sed
处理整个文件,这对于非常大的文件来说会令人窒息,从而违背了流编辑器的目的。如果可能的话,任何保留线路处理的解决方案都将是一个无法阅读的多个管道的老鼠窝。
If you insist on using sed
try:
如果你坚持使用sed
try:
sed -z 's/\n//g'
-z
tells sed
to use nulls as line separators.
-z
告诉sed
使用空值作为行分隔符。
Internally, a string in C
is terminated with a null. The -z
option is also a result of legacy, provided as a convenience for C
programmers who might like to use a temporary file filled with C
-strings and uncluttered by newlines. They can then easily read and process one string at a time. Again, the early assumptions about use cases impose artificial restrictions on user data.
在内部,字符串 inC
以 null 结尾。该-z
选项也是遗留的结果,为C
可能喜欢使用填充了C
-strings 且没有换行符的临时文件的程序员提供了便利。然后,他们可以轻松地一次读取和处理一个字符串。同样,关于用例的早期假设对用户数据施加了人为的限制。
If you omit the g
option, this command removes only the first newline. With the -z
option sed
interprets the entire file as one line (unless there are stray nulls embedded in the file), terminated by a null and so this also chokes on large files.
如果省略该g
选项,则此命令仅删除第一个换行符。使用该-z
选项sed
将整个文件解释为一行(除非文件中嵌入了杂散空值),以空值终止,因此这也会阻塞大文件。
You might think
你可能认为
sed 's/^/\x00/' | sed -z 's/\n//' | sed 's/\x00//'
might work. The first command puts a null at the front of each line on a line by line basis, resulting in \n\x00
ending every line. The second command removes one newline from each line, now delimited by nulls - there will be only one newline by virtue of the first command. All that is left are the spurious nulls. So far so good. The broken idea here is that the pipe will feed the last command on a line by line basis, since that is how the stream was built. Actually, the last command, as written, will only remove one null since now the entire file has no newlines and is therefore one line.
可能工作。第一个命令逐行在每行的前面放置一个空值,从而\n\x00
结束每一行。第二个命令从每行中删除一个换行符,现在由空值分隔 - 由于第一个命令,将只有一个换行符。剩下的就是虚假的空值。到现在为止还挺好。这里的坏主意是管道将逐行提供最后一个命令,因为这就是流的构建方式。实际上,正如所写的,最后一个命令只会删除一个空值,因为现在整个文件没有换行符,因此只有一行。
Simple pipe implementation uses an intermediate temporary file and all input is processed and fed to the file. The next command may be running in another thread, concurrently reading that file, but it just sees the stream as a whole (albeit incomplete) and has no awareness of the chunk boundaries feeding the file. Even if the pipe is a memory buffer, the next command sees the stream as a whole. The defect is inextricably baked into sed
.
简单的管道实现使用一个中间临时文件,所有输入都被处理并馈送到文件中。下一个命令可能正在另一个线程中运行,同时读取该文件,但它只是将流视为一个整体(尽管不完整)并且不知道提供文件的块边界。即使管道是内存缓冲区,下一个命令也会将流视为一个整体。缺陷难解难分sed
。
To make this approach work, you need a g
option on the last command, so again, it chokes on large files.
要使这种方法起作用,您需要g
在最后一个命令上添加一个选项,因此它会再次阻塞大文件。
The bottom line is this: don't use sed
to process newlines.
底线是:不要sed
用于处理换行符。
回答by Tony Su
Playing around with this further, A working solution is to remove the "*", it is unnecessary for both the original requirement to simply remove spaces as well if substituting an actual character is desired, as follows
进一步解决这个问题,一个可行的解决方案是删除“*”,如果需要替换实际字符,则原始要求也不需要简单地删除空格,如下所示
echo -n "Hello" | od -A n -t x1 | sed 's/ /%/g'
%48%65%6c%6c%6f
So, I consider this as an improvement answering the original Q since the statement now does exactly what is required, not just apparently.
因此,我认为这是对原始 Q 的改进,因为该语句现在完全符合要求,而不仅仅是表面上。
回答by trindflo
Combining the answers from TMS and i-always-rtfm-and-stfw, the following works under Windows using gnu-utils versions of the programs 'od', 'sed', and 'tr':
结合 TMS 和 i-always-rtfm-and-stfw 的答案,以下在 Windows 下使用 gnu-utils 版本的程序“od”、“sed”和“tr”运行:
echo "Hello"| tr -d '' | tr -d '\n' | tr -d '\r' | od -A n -tx1 | sed "s/ //g"
or in a CMD file as:
或在 CMD 文件中:
@echo "%1"| tr -d '' | tr -d '\n' | tr -d '\r' | od -A n -tx1 | sed "s/ //g"
A limitation on my solution is it will remove all double quotes (").
我的解决方案的一个限制是它会删除所有双引号 (")。
"tr -d ''" removes quote marks that the Windows 'echo' will include.
"tr -d '\r'" removes the carriage return, which Windows includes as well as '\n'.
The pipe (|) character must follow immediately after the string or the Windows echo will add that space after the string.
There is no '-n' switch to the Windows echo command.