[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

9.1.2 置換

tr は、set1set2 の両方が指定され、‘--delete’ (‘-d’) オプションが指定されていない場合は、文字の置換を行う。 tr は入力の中に set1 に存在する文字が現れるたびに、 それを set2 の対応する文字に置き換える。 入力中の set1 に存在しない文字は、読み飛ばして、変更しない。 ある文字が set1 中に 2 個以上存在し、set2 中のそれに対応する文字がすべて同じでない場合、 置換に使用するのは、最後の文字だけである。 たとえば、次の二つのコマンドは、同じ動作をする。

 
tr aaa xyz
tr a z

tr がよく使われるのは、アルファベットの小文字を大文字に変換するときである。 それには、いろいろな方法がある。例を三つほど挙げてみる。

 
tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ
tr a-z A-Z
tr '[:lower:]' '[:upper:]'

ただし、上記の a-z のような範囲指定の使用は、 可搬性がないことに注意していただきたい。

tr で置換を行う際には、普通 set1set2 を同じ長さにする。set1set2 より短いと、set2 の後尾にある余分な文字が無視されることになる。

逆に、set1set2 より長い場合は、可搬性がなくなる。 POSIX の規定では、結果は未定義なのだ。こうした場合、BSD の tr は、 set2 の最後の文字を必要なだけ繰り返して、set2set1 と同じ長さになるようにする。 System V の tr は、set1set2 と同じ長さに切り詰める。

デフォルトでは、GNU 版の tr は、この問題を BSD の tr と同じやり方で処理する。そして、‘--truncate-set1’ (‘-t’) オプションが指定されている場合のみ、System V の tr のように処理するのである。 このオプション (‘--truncate-set1’) は、置換以外の操作では無視される。

この問題で System V の tr の動作を選ぶと、 比較的よく使われる BSD 式の次の慣用表現が使えなくなる。

 
tr -cs A-Za-z0-9 '\012'

なぜなら、System V の動作では、アルファベットと数字以外のすべての文字を改行文字に変換するのではなく、 ゼロバイトしか (ASCII NUL 文字、それが set1 の補集合の最初の要素である) 改行文字に変換しないからだ。

ちなみに、上記の慣用表現は、システムによってはうまく動作しない。 なぜなら、範囲指定を使っているからであり、また、改行の 8 進数によるコードを 012 と決め込んでいるからでもある。tr が POSIX に準拠しているなら、 以下の方が、よりよい書き方である。

 
tr -cs '[:alnum:]' '[\n*]'

This document was generated on June 7, 2022 using texi2html 1.82.