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

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

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

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

上述命令的输出是:

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

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

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

答案1

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

你必须先将 i 的十进制值转换为其八进制值然后你必须使用 using 来打印它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

答案2

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

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

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

答案3

你需要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

答案4

如果像我一样,您希望printf尽可能保持格式字符串不变,请更改:

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

for i in `seq 32 127`; do printf %b "\0$(printf %o "$i")"; done
for i in `seq 32 127`; do printf %b "\x$(printf %x "$i")"; done  # not POSIX

(顺便说一句,POSIX 标准printf不包括\x格式字符串中允许的转义序列。)

由于关注点分离,我更喜欢使printf格式字符串尽可能保持不变。格式字符串关注的是格式化;参数适用于变化的数据。如果格式字符串中的扩展包含可以解释为格式说明符的内容,也可能会出现问题,如所讨论的这里在 C 编程环境中。此处还讨论了:ShellCheck linting 规则SC2059 不要在 printf 格式字符串中使用变量

相关内容