Linux tr 指令
tr
是 Linux 系统中一款轻量级且功能强大的文本处理工具,用于在标准输入中对字符进行转换、替换或删除。它是 Unix 哲学中“单一职责”工具的典范,广泛应用于 Shell 脚本、文本清洗、格式转换和数据预处理。tr
(translate 的缩写)通过映射字符集实现灵活的字符操作,支持大小写转换、字符替换、重复字符压缩和字符删除等功能。结合管道(|
),tr
可与其他命令(如 cat
、grep
、awk
)无缝集成,处理从简单字符串到复杂日志的各种场景。
📚 什么是 tr 指令?
概述
tr
是一款 Linux/Unix 命令行工具,用于对标准输入(stdin)的字符进行转换、替换或删除,并将结果输出到标准输出(stdout)。它由 POSIX 标准定义,属于 GNU coreutils 软件包,几乎所有 Linux 发行版(如 Ubuntu、CentOS、Arch Linux)默认包含。tr
通过指定两个字符集(SET1 和 SET2)实现字符映射,或通过选项删除特定字符。tr
的设计注重简单性和高效性,特别适合处理文本流、格式化输出和数据清洗,无需复杂脚本或编程语言。它的核心优势在于快速处理字符级操作,适合 Shell 脚本和管道工作流。
核心概念
- 字符集(SET):
tr
操作的输入和输出字符集合,如[a-z]
(小写字母)或[:digit:]
(数字)。 - 映射(Translation):将 SET1 中的字符替换为 SET2 中的对应字符,如
a
替换为A
。 - 删除(Deletion):通过
-d
选项移除指定字符。 - 压缩(Squeezing):通过
-s
选项压缩重复字符为单个字符。 - 标准输入/输出:
tr
仅从 stdin 读取,输出到 stdout,不直接处理文件。 - 字符类:支持 POSIX 字符类,如
[:alpha:]
(字母)、[:space:]
(空白)。 - 退出状态:
- 成功:返回 0。
- 失败(如无效参数):返回 1。
核心特点
- 轻量高效:专注于字符处理,资源占用低。
- 管道友好:与
echo
、cat
、grep
等无缝集成。 - 灵活映射:支持一对一字符替换和范围转换。
- 跨平台:POSIX 标准,兼容 Linux、BSD、macOS。
- 脚本适用:易于嵌入 Shell 脚本。
- 多编码支持:处理 UTF-8 和其他编码的文本。
基本语法
tr [选项] SET1 [SET2]
参数说明
- SET1:源字符集,指定要替换或删除的字符。
- SET2:目标字符集,指定替换后的字符(若需要替换)。
- 选项:
-c, --complement
:使用 SET1 的补集(非指定字符)。-d, --delete
:删除 SET1 中的字符。-s, --squeeze-repeats
:压缩 SET1 中重复的字符为单个。-t, --truncate-set1
:截断 SET1 长度以匹配 SET2。--help
:显示帮助信息。
- 字符集表示:
- 单个字符:如
abc
(字符 a、b、c)。 - 范围:如
a-z
(小写字母)、0-9
(数字)。 - POSIX 类:如
[:upper:]
(大写字母)、[:space:]
(空白)。 - 八进制:如
\040
(空格)。
- 单个字符:如
- 输入/输出:
- 从 stdin 读取,输出到 stdout。
- 文件处理需结合
cat
或重定向。
输出行为
- 对每行输入的字符逐一处理,按 SET1 和 SET2 映射输出。
- 删除或压缩操作直接修改文本流。
- 错误(如 SET1 和 SET2 长度不匹配)输出到 stderr。
注意事项
-
标准输入限制:
-
tr
不直接处理文件,需通过管道或重定向:cat file.txt | tr 'a' 'A'
-
-
字符集长度:
- 替换时,SET1 和 SET2 需匹配长度,或使用
-t
截断。
- 替换时,SET1 和 SET2 需匹配长度,或使用
-
编码影响:
- 多字节字符(如 UTF-8 中文)可能导致意外行为。
-
大小写敏感:
a
和A
为不同字符,需明确指定。
-
性能:
- 适合中小型文本,大文件可能需
sed
或awk
。
- 适合中小型文本,大文件可能需
-
安全性:
- 验证输入数据,避免处理恶意文本。
🔧 tr 的常见用途
应用场景
- 文本转换:大小写转换、字符替换(如空格转下划线)。
- 数据清洗:删除无关字符、压缩空白。
- 日志处理:格式化日志字段或提取信息。
- 脚本开发:在 Shell 脚本中处理字符串。
- 密码生成:生成随机字符串或清理输入。
- 格式化输出:调整命令输出格式。
🛠️ 基础用法与示例
准备工作
以下示例假设运行在 Bash shell(如 Ubuntu 24.04,当前时间为 2025-06-12 13:22 CST)。测试环境为标准 Linux 系统(如 Ubuntu、CentOS),确保 tr
可用(tr --version
)。示例使用临时文件 /tmp/data.txt
和管道操作,涉及文本、日志和命令输出。所有命令在终端或脚本中运行,假设系统支持 UTF-8 编码。
检查 tr
tr --version
输出示例:
tr (GNU coreutils) 9.4
创建测试文件
cat > /tmp/data.txt <<EOF
Hello, World!
This is a TEST.
123 ABC xyz
EOF
示例 1:大小写转换
命令
cat /tmp/data.txt | tr 'a-z' 'A-Z'
解释
- 将小写字母
[a-z]
替换为大写[A-Z]
。
输出示例
HELLO, WORLD!
THIS IS A TEST.
123 ABC XYZ
示例 2:字符替换
命令
echo "Hello, World!" | tr ',' ';'
解释
- 将逗号
,
替换为分号;
。
输出示例
Hello; World!
示例 3:删除字符
命令
cat /tmp/data.txt | tr -d 'o'
解释
-d
删除字符o
。
输出示例
Hell, Wrld!
This is a TEST.
123 ABC xyz
示例 4:压缩重复字符
命令
echo "Hello World!!!" | tr -s ' '
解释
-s
压缩连续空格为单个空格。
输出示例
Hello World!!!
示例 5:补集操作
命令
echo "Hello123" | tr -c 'a-z' '_'
解释
-c
选择小写字母[a-z]
的补集(非小写字母),替换为_
。
输出示例
Hello___
示例 6:处理数字
命令
echo "Phone: 123-456-7890" | tr -d '[:digit:]'
解释
- 删除所有数字
[:digit:]
。
输出示例
Phone: ---
🚀 常用选项与功能
🔍 字符转换
选项 | 描述 |
---|---|
SET1 SET2 | 将 SET1 的字符替换为 SET2 |
-t | 截断 SET1 以匹配 SET2 长度 |
示例
echo "abc" | tr -t 'abc' 'xyz'
📜 删除与压缩
选项 | 描述 |
---|---|
-d | 删除 SET1 中的字符 |
-s | 压缩 SET1 中重复字符 |
-c | 使用 SET1 的补集 |
示例
echo "aabbcc" | tr -s 'a-c'
📁 字符集
表示 | 描述 |
---|---|
a-z | 字母范围 |
[:alpha:] | 字母 |
[:digit:] | 数字 |
[:space:] | 空白字符 |
\n | 换行符 |
示例
echo "Test 123" | tr '[:lower:]' '[:upper:]'
🌟 高级用法
概述
tr
的高级用法涉及复杂字符映射、结合管道、处理多编码文本、日志清洗和自动化脚本,适合数据处理和系统管理。
🛡️ 1. 复杂字符映射
命令
echo "The year is 2025!" | tr 'a-zA-Z0-9' 'n-za-mN-ZA-M0-9'
解释
- 实现 ROT13 加密(字母旋转 13 位)。
输出示例
Gur lrne vf 2025!
🔍 2. 清理日志文件
测试文件
cat > /tmp/log.txt <<EOF
2025-06-12 13:00:01 [ERROR] 192.168.1.100: Connection failed
2025-06-12 13:00:02 [INFO] 192.168.1.101: Login successful
EOF
命令
cat /tmp/log.txt | tr -s '[:space:]' | tr '[]' '()'
解释
- 压缩空白,替换
[
和]
为(
和)
。
输出示例
2025-06-12 13:00:01 (ERROR) 192.168.1.100: Connection failed
2025-06-12 13:00:02 (INFO) 192.168.1.101: Login successful
🔄 3. 处理 CSV
测试文件
cat > /tmp/data.csv <<EOF
Alice,25,USA
Bob,30,UK
Charlie,35,Japan
EOF
命令
cat /tmp/data.csv | tr ',' ';'
解释
- 将 CSV 逗号分隔符替换为分号。
输出示例
Alice;25;USA
Bob;30;UK
Charlie;35;Japan
⚡ 4. 随机密码生成
命令
cat /dev/urandom | tr -dc 'a-zA-Z0-9' | head -c 12
解释
- 从
/dev/urandom
提取字母和数字,生成 12 位密码。
输出示例
kX9mP4nJ2vL8
🔐 5. 自动化脚本
脚本
#!/bin/bash
INPUT=/tmp/data.txt
cat "$INPUT" | tr '[:lower:]' '[:upper:]' > /tmp/data_upper.txt
cat "$INPUT" | tr -d '[:punct:]' > /tmp/data_clean.txt
echo "Processed files: data_upper.txt, data_clean.txt"
解释
- 将文本转为大写并清理标点,保存到不同文件。
输出示例
Processed files: data_upper.txt, data_clean.txt
⚠️ 使用 tr 时的注意事项
-
标准输入:
-
tr
不直接处理文件,需管道或重定向:tr 'a' 'A' < file.txt
-
-
字符集长度:
-
替换时 SET1 和 SET2 需匹配,或用
-t
:echo "abc" | tr -t 'abcd' 'xy'
-
-
编码问题:
-
多字节字符可能导致错误:
echo "中文" | tr '中' '英' # 可能失败
-
-
顺序敏感:
-
字符映射按顺序处理:
echo "abc" | tr 'abc' 'xyz' # a->x, b->y, c->z
-
-
性能:
-
大文件处理较慢,考虑
sed
:sed 's/a/A/g' large_file.txt
-
🛠️ 高级技巧与实战案例
概述
以下是高级技巧和实战案例,展示 tr
在复杂场景中的应用。
🖥️ 案例 1:格式化输出
命令
ps aux | tr -s '[:space:]' | cut -d ' ' -f 2,11-
解释
- 压缩
ps aux
的空白,提取 PID 和命令。
输出示例
PID COMMAND
1234 /bin/bash
5678 /usr/bin/python3
📦 案例 2:清理文件名
脚本
#!/bin/bash
for file in *.txt; do
new_name=$(echo "$file" | tr '[:upper:]' '[:lower:]' | tr ' ' '_')
mv "$file" "$new_name"
done
解释
- 将文件名转为小写,空格替换为下划线。
输出示例
My File.txt
重命名为my_file.txt
。
🔒 案例 3:日志清洗
脚本
#!/bin/bash
cat /tmp/log.txt | tr -d '[:punct:]' | tr -s '[:space:]' > /tmp/log_clean.txt
解释
- 删除标点,压缩空白。
输出示例
20250612 130001 ERROR 1921681100 Connection failed
20250612 130002 INFO 1921681101 Login successful
📈 案例 4:批量处理
脚本
#!/bin/bash
for file in /tmp/*.txt; do
cat "$file" | tr '[:space:]' '\n' | sort | uniq > "${file%.txt}_unique.txt"
done
解释
- 将空格转为换行,排序去重。
输出示例
- 创建
/tmp/data_unique.txt
。
🔧 案例 5:加密脚本
脚本
#!/bin/bash
encrypt() {
echo "$1" | tr 'A-Za-z' 'N-ZA-Mn-za-m'
}
decrypt() {
echo "$1" | tr 'N-ZA-Mn-za-m' 'A-Za-z'
}
echo "Original: Hello"
encrypted=$(encrypt "Hello")
echo "Encrypted: $encrypted"
echo "Decrypted: $(decrypt "$encrypted")"
解释
- 实现 ROT13 加密和解密。
输出示例
Original: Hello
Encrypted: Uryyb
Decrypted: Hello
📝 总结
tr
是 Linux 系统中简单而强大的文本处理工具,适用于字符转换、删除和压缩。本文从基础到高级,结合详细示例和注意事项,全面介绍了 tr
的功能。无论是格式化文本、清洗日志还是嵌入 Shell 脚本,tr
都能提供高效解决方案。