做什么
translate——逐字符转换或删除。处理整个字符集,不是字符串。
实战
转换
echo "Hello" | tr 'a-z' 'A-Z' # HELLO
echo "Hello" | tr 'A-Z' 'a-z' # hello
echo "abc123" | tr 'a-z' 'A-Z' # ABC123(数字不变)
# 字符替换
echo "hello world" | tr ' ' '_' # hello_world
echo "a,b,c" | tr ',' '\n' # 分行
# a
# b
# c
删除字符
echo "hello" | tr -d 'l' # heo(删所有 l)
echo "a1b2c3" | tr -d '0-9' # abc(删数字)
cat file.txt | tr -d '\r' # 删 Windows 换行(\r\n → \n)
压缩重复
echo "aaabbbccc" | tr -s 'a' # abbbccc
echo "hello world" | tr -s ' ' # hello world(多空格合一个)
大小写
echo "Hello" | tr '[:upper:]' '[:lower:]' # hello
echo "Hello" | tr '[:lower:]' '[:upper:]' # HELLO
字符类(POSIX)
| 类 | 含义 |
|---|---|
[:alpha:] |
字母 |
[:digit:] |
数字 |
[:alnum:] |
字母 + 数字 |
[:upper:] |
大写 |
[:lower:] |
小写 |
[:space:] |
空白 |
[:punct:] |
标点 |
[:print:] |
可打印 |
实战组合
# Windows → Unix 换行
tr -d '\r' < windows.txt > unix.txt
# 看文件用了哪些字符
cat file.txt | tr -d -c '[:print:]\n' | sort -u
# 拿 /etc/passwd 的用户名做 array
users=( $(cut -d: -f1 /etc/passwd | tr '\n' ' ') )
坑
- tr 只处理单字符或字符集——多字符模式用 sed
- tr 只从 stdin 读,不直接处理文件——总是要管道或重定向
tr 'a' 'B'是 a→B,长度必须匹配——tr 'a' 'BC'实际只用 B