次のコマンドを使用してすべてのASCII文字の文字列を出力したい
for i in `seq 32 127`; do printf "%c" $i; done
上記のコマンドの出力は次のようになります。
33333334444444444555555555566666666667777777777..............
各数字の最初の(左から)数字です。
このサイトを閲覧しながら、私の質問に対する回答を見つけました。CLIで印刷可能なすべてのASCII文字をどのように印刷しますか?しかし、元のコードスニペットが期待どおりにASCII文字を出力しない理由はまだ理解できません。
答え1
printf "%c" $i
Cで同様の方法を使用してASCIIコードを直接印刷することはできません。
あなたが最初にする必要がありますiの10進値を8進値に変換その後、usingを使用して印刷し、その8進数値の前にprintf
追加する必要があります。\
を印刷するには、A
10進数65を8進数(101)に変換してから、8進数の値を次のように印刷する必要があります。
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
より簡単で効率的なBashエスケープシーケンスに置き換えることができます。echo
16進数の場合:
for i in `seq 32 127`; do
echo -ne \\x$(printf %02x $i)
done
8進数の場合:
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リンティングルールSC2059 printf フォーマット文字列に変数を使用しないでください。。