改行とキャリッジリターンを\ nと\ rで印刷するには、echoまたはprintfを使用します。

改行とキャリッジリターンを\ nと\ rで印刷するには、echoまたはprintfを使用します。

私はシェルスクリプトのデバッグに使用しており、文字列を確認できるようにフォームから新しい行やキャリッジリターンを印刷するecho方法を知りたいと思います。可能ですか?echo\n\r\n\r

答え1

ksh93、zsh、またはbashのGNU実装またはprintf組み込み関数は、文字列printfに制御文字が含まれている場合、printf %qksh93で引用されているように文字列を出力するのと同様の操作を実行します。$'...'入力するまたは改行:

$ string=$'foo\rbar\n' ksh93 -c 'printf "%q\n" "$string"'
$'foo\rbar\n'
$ string=$'foo\rbar\n' zsh -c 'printf "%q\n" "$string"'
foo$'\r'bar$'\n'
$ string=$'foo\rbar\n' bash -c 'printf "%q\n" "$string"'
$'foo\rbar\n'
$ string=$'foo\rbar\n'; /usr/bin/printf "%q\n" "$string"
'foo'$'\r''bar'$'\n'

zshシェルでは、qqqqパラメータ拡張フラグを使用してこれらの引用$'...'符を無条件に使用することもできます。

$ s1=$'\r\n' s2=foobar
$ print -rC1 -- ${(qqqq)s1} ${(qqqq)s2}
$'\r\n'
$'foobar'

答え2

使用量の追跡

シェルによっては、トレースデバッグは、印刷できない文字を明示的な方法で表すことも、表示しない場合もあります。

x=$(printf a\\rb)
(set -x; LC_ALL=C; : "$x")

トレースは、それをサポートするシェルのシンボルを使用して生成されます$'…'。たとえば、ksh、mksh、bash はすべて印刷されます。

+ : $'a\rb'

ただし、dash や BusyBox などの他のシェルはキャリッジリターンを標準エラーとして出力するため、端末にあいまいな出力が発生します。これはあなたが避けたいものです。可能であれば、デバッグ中にbashまたは(m)ksh(またはshエミュレーションモードではzsh)でスクリプトを実行してください。

printfを使う

一部のprintf実装にはq指定子があります。%qに似ています%sが、出力をシェルに再解析できるようにいくつかの文字を引用します。結果も視覚的に明確です。たとえば、タブがとして印刷されます\t。 GNU printfの実装は%q

LC_ALL=C printf %q\\n "$x"

Linuxのダッシュでは、外部printfユーティリティを使用する必要があります/usr/bin/printf。 BusyBoxではこの機能を使用できません。

猫パイプを通して

多くの実装では、スペースの代わりにタブなどのcat印刷されない文字を視覚的に出力できます。^Iこれは明らかではありません。タブは2文字と区別できません^I

printf '%s\n' "$x" | cat -vet

16進ダンプ

16進ダンプを使用して出力を印刷できます。これを行う移植可能な方法はod

$ x=$(printf a\\tc\\rb); printf %s "$x" | od -tx1'
0000000 61 09 63 0d 62
0000005

BSDユーティリティhexdump(hd省略形) は *BSD および Debian ベースの Linux ディストリビューションで使用でき、印刷可能な文字も出力するので、より良いです。

$ x=$(printf a\\tc\\rb); printf %s "$x" | hd
00000000  61 09 63 0d 62                                    |a.c.b|
00000005

人気ユーティリティxxd(Vimと共に配布されますが、ほとんどのディストリビューションでは別々のパッケージとして利用可能です)出力形式は似ています。

$ x=$(printf a\\tc\\rb); printf %s "$x" | xxd -g1
00000000: 61 09 63 0d 62                                   a.c.b

難しい道

sedを使用すると、印刷できないすべての文字を1つずつ翻訳できます。移植可能なスクリプトを作成するには、印刷可能な文字を実際にsedに渡す必要があります。シェルスクリプトでsedを呼び出すと、それを使用してprintfsedスクリプトを設定できます。次のスクリプトは、最も一般的な制御文字をバックスラッシュエスケープとして印刷します。必要に応じて追加します。

#!/bin/sh
export LC_ALL=C
sed_script=$(printf '
s/\\\\/\\\\\\\\/g
s/'\''/\\\\'\''/g
s/\a/\\\\a/g
s/\b/\\\\b/g
s/\t/\\\\t/g
s/\f/\\\\f/g
s/\r/\\\\r/g
s/\033/\\\\e/g
$!s/$/\\\\n/
')
quoted=$(printf %sa "$2" | sed "$sed_script" | tr -d '\n')
printf "%s=\$'%s'\n" "$1" "${quoted%a}"

使用法:quoted-dump x "$x"

関連情報