trを使用すると、奇妙な動作を示す特定のサーバーがあります。以下は、稼働中のサーバーの例です。
-bash-3.2$ echo "abcdefghijklmnopqrstuvwxyz1234567890"|tr -d [a-z]
1234567890
-bash-3.2$
これは私にとって完全に理解されています。
ただし、これは「特殊」サーバーからのものです。
[root@host~]# echo "abcdefghijklmnopqrstuvwxyz1234567890"|tr -d [a-z]
abcdefghijklmnpqrstuvwxyz1234567890
ご覧のとおり、すべての小文字を削除すると失敗します。ただし、文字「o」は削除されます。
興味深い部分は次の2つの例ですが、私には理解できません。
[root@host~]# echo "abcdefghijklmnopqrstuvwxyz1234567890"|tr -d [a-n]
opqrstuvwxyz1234567890
[root@host~]# echo "abcdefghijklmnopqrstuvwxyz1234567890"|tr -d [a-o]
abcdefghijklmnpqrstuvwxyz1234567890
[root@host~]#
(最後の例では「o」が削除されました)
ここで何が起こっているのか知っている人はいますか?私が使用している他のLinuxボックスではそれを再現することはできません。
答え1
o
現在のディレクトリには次のファイルがあります。
foo> ls
foo> echo "abcdefghijklmnopqrstuvwxyz1234567890"|tr -d [a-z]
1234567890
foo> touch o
foo> echo "abcdefghijklmnopqrstuvwxyz1234567890"|tr -d [a-z]
abcdefghijklmnpqrstuvwxyz1234567890
[a-z]
一致するものが見つかると、シェルは文字列を展開します。
これをパス名拡張と呼びます。man bash
パス名拡張
語を分離した後、bashは-fオプションが設定されていない限り、文字*、?と[について各単語を検索します。 ...(...)
bash が拡張を実行します。
[...]は含まれている文字の1つと一致します。
答え2
何が問題なの?
シェルは引数を表示します[a-z]
。これはワイルドカードパターンです(全体的な状況)、これはすべての小文字と一致します。したがって、シェルはこのパターンに一致するファイル名を探します。 3つの状況があります。
- 現在、ディレクトリには単一の小文字のファイルがありません。その後、シェルはワイルドカードパターンをそのまま維持し、
tr
パラメータ-d
と[a-z]
。これはほとんどのコンピュータで発生します。 - 現在のディレクトリの個々のファイル名は単一の小文字で指定されます。その後、シェルはパターンをそのファイル名に拡張し、引数
tr
と-d
ファイル名を解決します。これはサーバーで発生し、文字が削除されたo
ことがわかるように、一致するファイルが呼び出されます。tr
o
- 現在ディレクトリにある複数のファイル名が単一の小文字で構成されています。その後、シェルはファイル名のリストと一致するようにパターンを拡張し、
tr
3つ以上の引数と-d
ファイル名を解決します。tr
その後にパラメータが必要なので-d
文句を言います。
あなたは何をすべきですか
コマンド引数に特殊文字がある場合は、エスケープする必要があります。パラメータを一重引用符で囲みます'…'
(これが最も簡単な方法であり、他の方法もあります)。一重引用符内では、一重引用符自体を除くすべての文字が自分自身を表します。パラメータに一重引用符がある場合それに変える'\''
。
tr -d '[a-z]'
しかし、これはまだ意図していないかもしれないことに注意してください!tr
小文字と角括弧を削除するコマンドです。等に該当しますtr -d ']a-z['
。tr '[]a-z'
小文字を削除するには、次のようにします。
tr -d a-z
パラメータtr
は文字セットです。正規表現またはワイルドカードパターンでは、括弧内に文字セットを入れて、その文字セットが文字セットであることを示します。しかし、tr
一度に1つのキャラクターにのみ適用されます。コマンドラインパラメータは次のとおりです。かっこ内に書く内容。
表現するには括弧が必要です。キャラクタークラス。正規表現では、括弧内に括弧を使用して文字クラスを表すことができます。たとえば、[[:lower:]]*
任意の数の小文字の一致、[[:lower:]_]*
任意の数の小文字、および下線の一致などが可能です。引数でtr
括弧なしでセットが必要なので、tr -d '[:lower:]'
小文字の削除、tr -d '[:lower:]_'
小文字、アンダースコアの削除などを行います。