tr(translate)は「文字を別の文字に置き換える・削除する・圧縮する」コマンドです。
sed や awk ほど複雑な構文はなく、シンプルな1文字単位の変換に特化しているため、パイプと組み合わせたテキスト処理で非常に重宝します。
基本構文
tr [オプション] SET1 [SET2]
- SET1: 変換元の文字集合
- SET2: 変換先の文字集合(SET1の各文字がSET2の対応する文字に置き換わる)
- ファイルを直接指定することはできず、標準入力からのみ読み込む
ステップ1:大文字・小文字の変換
最もよく使われる使い方です。
# 小文字 → 大文字
echo "hello world" | tr 'a-z' 'A-Z'
# 出力: HELLO WORLD
# 大文字 → 小文字
echo "Hello World" | tr 'A-Z' 'a-z'
# 出力: hello world
a-z のようなハイフン記法で文字の範囲を指定できます。
ステップ2:特定の文字を別の文字に置き換える
# コロン(:)をスペースに変換(/etc/passwd の確認に便利)
echo "root:x:0:0:root:/root:/bin/bash" | tr ':' ' '
# 出力: root x 0 0 root /root /bin/bash
# スペースをアンダースコアに変換
echo "hello world foo bar" | tr ' ' '_'
# 出力: hello_world_foo_bar
SET1 と SET2 の文字数が同じであれば、複数文字を一括置換できます。
# a→1, b→2, c→3 に変換
echo "abcabc" | tr 'abc' '123'
# 出力: 123123
ステップ3:文字の削除(-d オプション)
-d(delete)オプションで、指定した文字を削除できます。
# 数字をすべて削除
echo "user123password456" | tr -d '0-9'
# 出力: userpassword
# 改行を削除してファイル内容を1行にまとめる
cat /etc/shells | tr -d '\n'
# スペースを削除
echo "h e l l o" | tr -d ' '
# 出力: hello
ステップ4:連続する同じ文字を1つに圧縮(-s オプション)
-s(squeeze-repeats)オプションで、連続して繰り返す文字を1つにまとめます。
# 連続するスペースを1つのスペースに
echo "hello world foo" | tr -s ' '
# 出力: hello world foo
# 連続する改行を1つの改行に(空白行の削除)
cat somefile.txt | tr -s '\n'
# 連続するゼロを1つに
echo "10000000" | tr -s '0'
# 出力: 10
ステップ5:文字クラスを使う
[:クラス名:] という記法で文字クラスを指定できます。
| 文字クラス | 意味 |
|---|---|
[:alpha:] | 英字(a-z, A-Z) |
[:digit:] | 数字(0-9) |
[:alnum:] | 英数字 |
[:upper:] | 大文字 |
[:lower:] | 小文字 |
[:space:] | 空白文字(スペース・タブ・改行など) |
[:punct:] | 記号・句読点 |
# 文字クラスを使った大文字→小文字変換
echo "Hello World 123" | tr '[:upper:]' '[:lower:]'
# 出力: hello world 123
# 数字以外をすべて削除
echo "abc123def456" | tr -d '[:alpha:]'
# 出力: 123456
ステップ6:補集合(-c オプション)
-c(complement)オプションはSET1で指定しなかった文字を対象にします。
# 英数字以外をすべてスペースに変換
echo "hello, world! 123" | tr -cs '[:alnum:]' ' '
# 出力: hello world 123
# 改行以外の空白文字をすべて削除
echo -e "hello\tworld\n" | tr -d -c '[:print:]\n'
-c と -s や -d を組み合わせると強力です。
実践:パイプと組み合わせた活用例
CSVのフィールドセパレータを変換する
echo "name,age,city" | tr ',' '\t'
# 出力: name age city(タブ区切りに変換)
ファイルの単語を1行ずつ表示する
echo "the quick brown fox" | tr ' ' '\n'
# 出力:
# the
# quick
# brown
# fox
パスワードに使えないような文字を除去する
echo "P@ssw0rd!#" | tr -d '[:punct:]'
# 出力: Pssw0rd
/etc/passwd からユーザー名だけを抽出する
cut -d: -f1 /etc/passwd | tr '[:lower:]' '[:upper:]'
# ユーザー名を大文字で表示
練習問題
問題1
次のコマンドの出力を答えてください。
echo "Linux is Great" | tr 'a-z' 'A-Z'
問題2
文字列 "2026-09-18" からハイフン(-)を削除して "20260918" と出力するコマンドを書いてください。
問題3
次のコマンドは何をするものですか?
cat /etc/passwd | tr ':' '\n'
問題4
文字列 "hello world" の連続するスペースを1つにまとめ、さらに小文字を大文字に変換して出力するコマンドをパイプでつないで書いてください。
練習問題の答え
答え1
LINUX IS GREAT
小文字の a-z をすべて対応する大文字 A-Z に変換します。
答え2
echo "2026-09-18" | tr -d '-'
-d オプションでハイフン文字を削除します。
答え3
/etc/passwd の各行にあるフィールド区切り文字のコロン(:)をすべて改行(\n)に置き換えます。結果として、各フィールドが1行ずつ表示されます。
答え4
echo "hello world" | tr -s ' ' | tr 'a-z' 'A-Z'
tr -s ' 'で連続するスペースを1つに圧縮tr 'a-z' 'A-Z'で小文字を大文字に変換
出力: HELLO WORLD
まとめ
| オプション | 動作 |
|---|---|
| なし | SET1の文字をSET2の文字に変換 |
-d | SET1の文字を削除 |
-s | SET1の連続する文字を1つに圧縮 |
-c | SET1の補集合(指定外の文字)を対象にする |
tr はシンプルながら、cut・sort・grep などと組み合わせることでテキスト処理のパイプラインを大幅に強化できます。まずは大文字小文字の変換や文字削除から試して、徐々に文字クラスや補集合の活用に挑戦してみましょう。