![tr -c '[a-zA-Z]' '\n' はすべての補数文字を置き換えません](https://rvso.com/image/76452/tr%20-c%20'%5Ba-zA-Z%5D'%20'%5Cn'%20%E3%81%AF%E3%81%99%E3%81%B9%E3%81%A6%E3%81%AE%E8%A3%9C%E6%95%B0%E6%96%87%E5%AD%97%E3%82%92%E7%BD%AE%E3%81%8D%E6%8F%9B%E3%81%88%E3%81%BE%E3%81%9B%E3%82%93.png)
スクリプトを書いていて、アルファベット ([a-zA-Z]) 以外のすべての文字を改行に置き換えたいと思いました。定義上、-c フラグ (セット補完) を使用すると、tr は SET1 にないすべての文字を SET2 で指定された文字に置き換えるはずです。しかし、期待どおりに動作しません... これを試してください:
echo '[[:lower:]]' | tr -c '[a-zA-Z]' '\n'
出力は次のようになります:
[[
lower
]]
ご覧のとおり、列は置き換えられますが、置き換えられるはずの角括弧は置き換えられません。
誰かこれを明確に説明できますか?
答え1
tr
その正規表現スタイルでは文字クラスを解釈しません。
[a-zA-Z]
は のセットとして解釈され、 からまで[
の文字の範囲と となります。a
z
]
したがって、その補集合は、 を除くすべての文字、からまで[
の文字の範囲、およびを含む文字の集合です。a
z
]
そのため[
、 と は]
置き換えられません。
アルファベット以外の文字を置き換えるには、a-zA-Z
置き換える文字セットの補数として指定します。
echo '[[:lower:]]' | tr -c 'a-zA-Z' '\n'
% echo '[[:lower:]]' | tr -c 'a-zA-Z' '\n'
lower
%