translate の略である tr コマンドは、stdin から読んだ文字を変換、削除、圧縮します。通常の入力ファイルオペランドは受け取らないため、パイプまたは入力リダイレクトでデータを渡します。
基本構文は次のとおりです。
tr [OPTIONS] SET1 [SET2]
テキスト操作 · レッスン 13
標準入力ストリームの文字集合を変換、削除、圧縮する方法を学びます。
translate の略である tr コマンドは、stdin から読んだ文字を変換、削除、圧縮します。通常の入力ファイルオペランドは受け取らないため、パイプまたは入力リダイレクトでデータを渡します。
基本構文は次のとおりです。
tr [OPTIONS] SET1 [SET2]
tr が扱うのは文字集合で、単語や一般的な正規表現ではありません。完全な単語、行構造、周囲の文脈に依存する変換には別のツールを使います。
2 つの集合を指定すると、SET1 の文字を同じ位置にある SET2 の文字へ対応付けます。
$ echo "hello world" | tr a-z A-Z
HELLO WORLD
$ echo "2026-06-23" | tr '-' '/'
2026/06/23
$ echo "abc123" | tr 'abc' 'ABC'
ABC123
集合式はシェルにそのまま渡るよう引用します。SET1 に含まれない文字は変更されません。
printf '%s\n' 'abc123' | tr 'abc' 'ABC' は何を表示しますか?
1 つの集合と -d を使うと、一致するすべての文字を削除します。
$ echo "My address is 123 Main Street" | tr -d '0-9'
My address is Main Street
$ echo "Hello, world!" | tr -d '[:punct:]'
Hello world
$ printf "one\ntwo\nthree\n" | tr -d '\n'
onetwothree
数字は完全な数値トークンではなく 1 文字ずつ削除されます。文字クラスは現在のロケールで定義される集合を表します。改行を削除すると代わりの区切りを入れずに行が連結されます。
:::single-choice{#tr-delete-digits} 他の文字を変えず、stdin からすべての数字を削除するコマンドはどれですか?
::option[tr -d '[:digit:]']{#tr-delete-digit-class .correct explanation="-d は入力ストリームから数字クラスの全文字を削除します。"}
::option[tr -s '[:digit:]']{#tr-squeeze-digits explanation="-s は連続する数字を圧縮しますが、各並びから 1 文字は残します。"}
::option[tr '[:digit:]']{#tr-one-set-no-delete explanation="通常の変換には第 2 集合が必要で、集合だけでは削除を要求しません。"}
:::
-s SET は、集合内の同じ文字が続く並びを 1 文字へ置き換えます。
$ echo "Hello World, how are you?" | tr -s ' '
Hello World, how are you?
$ printf "one\n\n\nTwo\n" | tr -s '\n'
one
Two
最初の集合に含まれるのは通常の空白だけなので、タブや改行はそのコマンドでは圧縮されません。
stdin 内の通常の空白の連続をすべて 1 個へ減らすコマンドはどれですか?
一般的な文字クラスには [:lower:]、[:upper:]、[:digit:]、[:alpha:]、[:alnum:]、[:space:]、[:punct:] があります。
$ echo "linux journey" | tr '[:lower:]' '[:upper:]'
LINUX JOURNEY
$ echo "user@example.com!" | tr -cd '[:alnum:]'
userexamplecom
-c は SET1 の補集合、つまり集合にないすべての文字を意味します。-d と組み合わせれば選択した種類だけを残せます。この例では改行も英数字でないため削除されます。レコード境界が重要なら区切りを意図的に残してください。
tr -cd '[:alnum:]' は stdin に何をしますか?
処理を分けたほうが明確なら複数の tr を接続できます。
$ echo "Hello,,, world!!!" | tr -d '[:punct:]' | tr -s ' '
Hello world
$ printf "name\tlevel\npete\tbeginner\n" | tr '\t' ','
name,level
pete,beginner
$ tr '[:lower:]' '[:upper:]' < names.txt
tr は stdin を読むため、ファイルは < で渡せます。結果を保存するなら stdout を別ファイルへ送り、読み取り前に入力を切り詰める同じパスへのリダイレクトは避けます。
:::single-choice{#tr-read-file-input} tr に names.txt を stdin として読ませ、小文字を大文字へ変換するコマンドはどれですか?
::option[tr names.txt '[:lower:]' '[:upper:]']{#tr-file-operand explanation="tr は通常の入力ファイル名をこの形で受け取らず、余分なオペランドで構文が不正になります。"}
::option[tr -d '[:lower:]' < names.txt]{#tr-delete-lowercase explanation="ファイルの読み方は正しいですが、小文字を変換せず削除します。"}
::option[tr '[:lower:]' '[:upper:]' < names.txt]{#tr-input-redirection .correct explanation="シェルが names.txt を stdin で開き、tr が小文字クラスを大文字クラスへ対応付けます。"}
:::
文字単位のストリーム変換を練習するには、次のラボを試してください。
レッスン完了
目的を絞った tr 操作で文字ストリームを変換できるようになりました。
対応する集合間で文字を変換する。
-d で選択した文字を削除する。
-s で連続する文字を圧縮する。
ロケール依存のクラスと補集合を意図的に使う。
ファイルオペランドではなく stdin から入力を渡す。