将十进制打印为ASCII字符,我的命令未按预期输出


14

我想使用以下命令输出所有ascii字符的字符串

for i in `seq 32 127`; do printf "%c" $i; done

上面命令的输出是:

33333334444444444555555555566666666667777777777..............

它是每个数字的第一个(从左到右)数字。

通过这个站点,我遇到了问题的答案如何在CLI中打印所有可打印的ASCII字符?,但是我仍然不明白为什么我的原始代码片段没有按预期输出ascii字符。


1
POSIX对此进行了规定,以下是其正确原因的一个comp.unix.shell线索;)
sr_

@sr_感谢您指出线程。它有我想要的解释。
Ifthikhan 2012年

Answers:


13

您不能使用printf "%c" $iC中的like 直接打印ascii代码。

您必须首先将i的十进制值转换为其八进制值,然后使用printf\在其各自的八进制值前放置它来进行打印。

要进行打印A,您必须将十进制的65转换为八进制,即101,然后将八进制值打印为:

printf "\101\n"

这将打印A

因此,您必须将其修改为:

for i in `seq 32 127`; do printf \\$(printf "%o" $i);done;

但是通过使用awk您可以像使用C语言一样直接打印

awk 'BEGIN{for(i=32;i<=127;i++)printf "%c",i}';echo

7
In bashzsh可以在没有循环且没有外部命令的情况下完成printf $(printf '\%o' {32..127})
manatwork,2012年

@manatwork:没错,..非常感谢您指出这一点..
pradeepchhetri

1
@pradeepchhetri:谢谢您的详细答复,它似乎涵盖了大多数必需的细节(因此,我选择您的回答)。但是我想它错过了重要的信息,可以在unix.derkeiler.com/Newsgroups/comp.unix.shell/2007-07/…的以下消息中找到。它指出:“如果相应的转换说明符为b,c或s,则应将参数操作数视为字符串。”
Ifthikhan 2012年

不是(char)(127)退格键或类似的东西。不管它是什么,它都显示为十六进制框之一或它们被称为的任何东西。如果只需要“可打印的”(即可读的),则转到126。此外,八进制的想法也不错。那很聪明;我在想用十六进制表示(例如printf '\x%x; {32..126}...或127,因为你们所有人也都这样做了),但这是行不通的。八进制可以节省一天!:)最后,@ Ifthikhan,我不确定您的意思。awk通常使用C样式的命令,并且不使用其他任何地方%c。使用八进制数字与使用一字节字符不同。
迪伦

3

%c 将关联的参数解释为char:仅显示给定参数的第一个字符

您似乎已经有一种打印它们的方法,但这是一个变体。

for i in `seq 32 127`; do printf "\x$(printf "%x" $i) $i"; done

0

printf只需要一次;您可以用printf更简单,更高效的echoBash转义序列代替一种用法:

带有十六进制:

for i in `seq 32 127`; do
  echo -ne \\x$(printf %02x $i)
done

八进制:

for i in `seq 32 127`; do
  echo -ne \\0$(printf %03o $i)
done
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.