tr
文字列の「違法」文字がすべて「許可」文字セットの外側にある「違法」文字を置き換える文字(つまりこれは許可される文字セットに追加されます。ただし、この-c
オプションを明示的な反復*
指定子または「セット2」の暗黙的な拡張とともに使用すると、tr
追加出力用の代替文字のインスタンスです。
また現れる
- 「許可される」文字を
a-n
文字通りに指定しますabcdefghijklmn
。 - 代替文字をにしておきます
z
。 - 入力文字列を
hell
またはのままにしますhello
。予想される出力文字列はthenhell
とですhellz
。
デモ
無効な文字が存在します。暗黙のセット 2 拡張子です。
$ echo "hello" | tr -c 'abcdefghijklmn' 'z' hellzz
予想される出力はです
hellz
。文字のみが許可され、暗黙のセット2拡張子です。
$ echo "hell" | tr -c 'abcdefghijklmn' 'z' hellz
予想される出力はです
hell
。無効な文字が存在します。 2つの拡張子を明示的に設定しました。
$ echo "hello" | tr -c 'abcdefghijklmn' '[z*]' hellzz
予想される出力はです
hellz
。文字のみが許可され、明示的に2つの拡張子を設定します。
$ echo "hell" | tr -c 'abcdefghijklmn' '[z*]' hellz
予想される出力はです
hell
。echo-pipeの代わりにhere-stringを使用しても同じことが起こります(実際、here-stringは私がこの効果を最初に見つけたときに使用した設定でした)。
$ tr -c 'abcdefghijkl' '[z*]' <<< "hello" hellzz
tr
なぜここに1つを追加するのですかz
?
これはLinuxでbash、UTF-8ロケールを使用し、tr
GNU coreutils 8.25および8.30を使用します。
ベストアンサー1
echo
これは、印刷するように指示した内容の末尾に改行文字が追加されるためです。ここで文字列を使用しても同様です。
したがって、echo "hello"
実際に印刷されますhello\n
。
$ echo hello | od -c
0000000 h e l l o \n
0000006
これがまさにあなたがこれを見る理由です:
$ echo "hell" | tr -c 'abcdefghijklmn' 'z'
hellz$
そこには末尾の改行はなく、$
私のプロンプトが最後に表示されます。これは、最後に印刷された内容が置き換えられるためz
です。\n
hello\n
z
printf
$ printf "hello" | tr -c 'abcdefghijklmn' 'z'
hellz$
(printf %s "$string"
任意の文字列の場合はno )printf "$string"
またはecho
、それをサポートしているものを使用している場合は、以下を使用してくださいecho -n
。
$ echo -n "hello" | tr -c 'abcdefghijklmn' 'z'
hellz$
echo
または、標準のUNIX(およびオプションがすべて有効な場合は組み込みのような)がある場合は、echo
出力を停止する原因を使用してください。bash
posix
xpg_echo
\c
echo
$ echo 'hello\c' | tr -c 'abcdefghijklmn' 'z'
hellz$
ただし、出力がまだ正しいテキストになるように、入力に対応する行区切り文字を保持しようとする可能性が高くなります。
printf '%s\n' "$string" | tr -c 'abcdefghijklmn\n' '[z*]'
(代わりに標準のPOSIX構文が使用され、改行をより明確に追加し、文字で始まる、または文字を含むprintf
文字列に関連する問題を回避します。)echo
-
\
tr
また、実装によっては個別に文字としてデコードできないバイトが残ることがありますが(変更されませんz
)、他の場合(たとえば、GNU)では、tr
文字ごとに単一の文字(およびロケールセット)バイトを持つテキストに対してのみ機能します。
sed
別のアプローチは、少なくともGNU実装ではこれに関してよりうまく機能する方法を使用することです。
sed 's/[^abcdefghijklmnz]/z/g'
sed
その仕事をするコンテンツ改行は自動的に維持されます。