$IFS
変数の値を表示したいのですが、これには印刷できない文字が含まれている可能性があります(例:改行)。
そのために次のコマンドを使用しました。
echo -n "$IFS" | hexdump -C
私の場合、それはうまくいきました。
しかし、このコマンドの使用に何か問題がありますか?たとえば、echo
はstdout
に出力する前に、印刷できない文字を他の文字に置き換えますか、それとも他の問題がありますか?
特にIFS
の場合は、絶対に引用したいと思います。それ以外の場合は、何も起こらないためです。あなたはすでにそれをしたので、そこに問題はありません。
echo
については、シェルに依存します。 echo
の一部のバージョンは、デフォルトでバックスラッシュエスケープを処理しますが、処理しないものもあります。 Bashにはありませんが、zshにはあります。
$ bash -c 'echo "foo\nbar"'
foo\nbar
$ zsh -c 'echo "foo\nbar"'
foo
bar
代わりにprintf
を使用することをお勧めします:printf "%s" "$IFS" | hexdump -C
。
printf "%q" "$IFS"
はBashとzshでも動作します。
これは、BashがNULバイト(\0
)まったく、zshはできます。バッシュ:
$ var=$'foo\0bar'
$ printf "%q\n" "$var"
foo
zsh:
$ var=$'foo\0bar'
$ printf "%q\n" "$var"
foo$'\0'bar
文字列の視覚的表現を与える際のいくつかのさまざまなアプローチ:
$ printf %s "$IFS" | od -vtc -to1
0000000 \t \n \0
040 011 012 000
0000004
$ printf '%s\n' "$IFS" | LC_ALL=C sed -n l
\t$
\000$
(最後の行が改行で終わっていない場合のsed
の動作は指定されていないため、追加の\n
が必要です)。 POSIX sh
は、私のzshがここで行うように、$IFS
にNULがありません。入力にNULが含まれている場合のsed
の動作は指定されていません。
typeset -p
(ksh、zsh、bash、yash)を使用すると、一部の文字列に対して明確な出力が得られる場合があります。
$ ksh93 -c 'typeset -p IFS'
IFS=$' \t\n'
$ zsh -c 'typeset -p IFS'
typeset IFS=$' \t\n\C-@'
$ mksh -c 'typeset -p IFS'
typeset IFS=$' \t\n'
$ a=$'\u00e9e\u301\u200b' ksh -c 'typeset -p a'
typeset -x a=$'\u[e9]e\u[301]\u[200b]'
しかし、後者(急性アクセントとゼロ幅スペース文字を組み合わせたUnicodeを使用)の場合、zsh/mkshは役に立ちません(LC_ALL=C typeset -p a
とmksh -o utf8-mode
を併用しても)。 bash
の出力は、通常、端末に送信したときに明確になります。
printf %q
with GNU printf
and printf
builtin ksh93
、zsh
and bash
:
$ a=$'\u00e9e\u301\u200b' bash -c 'printf "%q\n" "$IFS" "$a" ""'
$' \t\n'
éé
''
$ a=$'\u00e9e\u301\u200b' ksh -c 'printf "%q\n" "$IFS" "$a" ""'
$' \t\n'
$'\u[e9]e\u[301]\u[200b]'
''
\ $'\t'$'\n'$'\0'
éé
''
$ a=$'\u00e9e\u301\u200b' sh -c '/usr/bin/printf "%q\n" "$IFS" "$a" ""'
' '$'\t\n'
éé
''
$ a=$'\u00e9e\u301\u200b' zsh -c 'LC_ALL=C printf "%q\n" "$IFS" "$a" ""'
\ $'\t'$'\n'$'\0'
$'\303'$'\251'e$'\314'$'\201'$'\342'$'\200'$'\213'
''
$ a=$'\u00e9e\u301\u200b' bash -c 'LC_ALL=C printf "%q\n" "$IFS" "$a" ""'
$' \t\n'
$'\303\251e\314\201\342\200\213'
''
q
内のqq
、qqq
、qqqq
、zsh
パラメータ展開フラグ。
さまざまなタイプの引用について、qqqq
は$'...'
の引用です:
$ a=$'\u00e9e\u301\u200b' zsh -c 'print -r -- ${(qqqq)a}'
$'éé'
$ a=$'\u00e9e\u301\u200b' zsh -c '(){local LC_ALL=C; print -r -- ${(qqqq)a}}'
$'\303\251e\314\201\342\200\213'
q
とq+
もあり、それはneedであるものに対してのみ引用符を使用します(ただし、これらのunicodeのものにはまだ注意が必要です)。
hex-dumper:hexdump
、hd
、xxd
... printf %s "$var"
(またはprint -rn -- "$var"
の出力をフィードしますksh/zsh、またはecho -nE - "$var"
with zsh
...)。
cat -vte
またはcat -A
uconv -x hex
文字のUnicodeコードポイント(エンコードのバイトの16進値ではなく)、UTF-8のみ(ロケールの有効なテキストである場合はiconv -t utf-8
で入力を前処理できます)エンコーディング)
uconv -x name
はキャラクター名
recode ..dump
。 16進数と名前の両方ですが、Unicode文字の数は少なくなっています(新しいバージョンのUnicodeでは更新されません)。ただし、UTF-8以外のロケールで動作します。
Bashで機能しない唯一の文字はnullです。
$ var="$(Perl -wE 'print map chr, 0 .. 255')"
$ echo -n "$var" | xxd
0000000: 0102 0304 0506 0708 090a 0b0c 0d0e 0f10 ................
0000010: 1112 1314 1516 1718 191a 1b1c 1d1e 1f20 ...............
0000020: 2122 2324 2526 2728 292a 2b2c 2d2e 2f30 !"#$%&'()*+,-./0
0000030: 3132 3334 3536 3738 393a 3b3c 3d3e 3f40 123456789:;<=>?@
0000040: 4142 4344 4546 4748 494a 4b4c 4d4e 4f50 ABCDEFGHIJKLMNOP
0000050: 5152 5354 5556 5758 595a 5b5c 5d5e 5f60 QRSTUVWXYZ[\]^_`
0000060: 6162 6364 6566 6768 696a 6b6c 6d6e 6f70 abcdefghijklmnop
0000070: 7172 7374 7576 7778 797a 7b7c 7d7e 7f80 qrstuvwxyz{|}~..
0000080: 8182 8384 8586 8788 898a 8b8c 8d8e 8f90 ................
0000090: 9192 9394 9596 9798 999a 9b9c 9d9e 9fa0 ................
00000a0: a1a2 a3a4 a5a6 a7a8 a9aa abac adae afb0 ................
00000b0: b1b2 b3b4 b5b6 b7b8 b9ba bbbc bdbe bfc0 ................
00000c0: c1c2 c3c4 c5c6 c7c8 c9ca cbcc cdce cfd0 ................
00000d0: d1d2 d3d4 d5d6 d7d8 d9da dbdc ddde dfe0 ................
00000e0: e1e2 e3e4 e5e6 e7e8 e9ea ebec edee eff0 ................
00000f0: f1f2 f3f4 f5f6 f7f8 f9fa fbfc fdfe ff ...............
printf
はecho
よりも移植性がありますが、私のシステムとシェル(bash)の場合、出力はまったく同じです。
printf %s "$var"