Linux tr命令详细使用教程

简介: tr是Linux中轻量高效的字符处理命令,专注字符翻译、重复压缩与指定删除,纯内存流式处理。本文详解其语法、四大选项(-c/-d/-s/-t)、字符集写法(范围/转义/字符类等)及10+实战场景,助新手快速掌握核心用法。

tr命令是Linux系统中处理字符的“轻量小能手”,主打字符翻译、重复字符压缩、指定字符删除三大核心功能,它从标准输入读取字符流,处理后直接输出到标准输出,没有文件读写的能力,纯内存字符流处理,在日常文本快速处理、脚本编写中特别实用。

本文会从基础语法、核心选项、字符集表示方法,到经典实用场景,用浅显的语言+丰富示例讲透tr命令,新手也能快速上手。

一、初识tr命令:语法与核心作用

1. 基本语法

tr [OPTION]... STRING1 [STRING2]
  • OPTION:tr的功能选项,必须写在字符集前面,多个选项可组合使用;
  • STRING1/STRING2:字符集,tr会将其解析为字符数组ARRAY1/ARRAY2,绝大多数场景下STRING2可选;
  • 核心作用:根据选项规则,对输入中属于ARRAY1的字符进行处理,非ARRAY1的字符会原封不动输出。

2. 核心处理能力

tr命令本质上只做四类操作,所有用法都是这四类的组合:

  1. 字符翻译(需同时指定STRING1和STRING2);
  2. 仅压缩重复字符(仅指定STRING1+对应选项);
  3. 仅删除指定字符(仅指定STRING1+对应选项);
  4. 先删除指定字符,再压缩结果中的重复字符(组合选项)。

二、tr核心选项详解

tr的选项不多,共4个核心功能选项,均支持短选项长选项,下面逐个讲解每个选项的作用,并搭配简单示例帮助理解(示例中用echo提供标准输入,是tr最常用的使用方式)。

1. -c/--complement:取字符集的补集

作用:不处理STRING1中的字符,反而处理所有不在STRING1中的字符(补集),字符按ASCII码升序排列。
注意:在UTF-8等多字节字符集的系统中使用需谨慎,易出现非预期结果,建议加LC_ALL=C强制单字节解析。
示例:保留输入中的数字,将其他所有字符替换为星号*

# 输入:abc123def456,保留数字,其余替换为*
echo "abc123def456" | tr -c '0-9' '*'
# 输出:***123***456

2. -d/--delete:删除指定字符

作用:删除输入中属于STRING1的所有字符,此选项下无需指定STRING2(指定了也会被忽略)。
核心:纯删除,无其他额外处理。
示例1:删除输入中的小写字母

echo "Hello123World456" | tr -d 'a-z'
# 输出:H123W456

示例2:删除输入中的特殊符号@#

echo "test@123#linux" | tr -d '@#'
# 输出:test123linux

3. -s/--squeeze-repeats:压缩重复字符

作用:将输入中连续重复的指定字符,压缩为单个字符;若和翻译/删除选项组合,会在翻译/删除后执行压缩。

  • 仅用-s时:压缩STRING1中的连续重复字符;
  • 组合其他选项时:压缩最后一个指定字符集中的连续重复字符。
    示例1:压缩连续的数字
    echo "111222333linux444" | tr -s '0-9'
    # 输出:123linux4
    
    示例2:压缩连续的空格(日常最实用的场景之一)
    echo "linux  is  a  free  os" | tr -s ' '
    # 输出:linux is a free os
    

4. -t/--truncate-set1:截断字符集1

作用:仅在字符翻译场景下生效(同时指定STRING1和STRING2),将STRING1截断为和STRING2相同的长度,避免字符集长度不一致导致的非预期翻译。
背景:GNU tr默认兼容BSD风格,若STRING1比STRING2长,会将STRING2的最后一个字符重复,补齐到和STRING1同长度;而-t会让tr按System V风格处理,直接截断STRING1。
示例:对比有无-t的翻译结果

# 无-t:STRING1(abc)比STRING2(xy)长,将y重复,a→x,b→y,c→y
echo "abc" | tr 'abc' 'xy'
# 输出:xyy

# 有-t:截断STRING1为ab,a→x,b→y,c不处理(原封不动)
echo "abc" | tr -t 'abc' 'xy'
# 输出:xyc

三、tr的字符集花式表示法

tr的STRING1和STRING2不是正则表达式,只是字符数组,但支持多种字符集简写方式,这是tr的核心灵活点,也是新手容易搞混的地方,下面讲透所有合法的字符表示方法。

1. 普通字符

直接写字符即可,适用于少量字符的场景,例如:

# 将a换成x,b换成y
echo "abcab" | tr 'ab' 'xy'
# 输出:xycxy

2. 转义序列

支持常见的转义字符,用于表示不可见的控制字符,核心转义序列如下:
| 转义序列 | 含义 | 转义序列 | 含义 |
|----------|--------------|----------|--------------|
| \a | 响铃(Ctrl+G)| \n | 换行(Ctrl+J)|
| \b | 退格(Ctrl+H)| \r | 回车(Ctrl+M)|
| \f | 换页(Ctrl+L)| \t | 制表符(Tab)|
| \v | 垂直制表符 | \ | 反斜杠本身 |
| \OOO | 八进制数表示的字符(1-3位) | - | - |

示例:将制表符\t替换为空格

echo "linux\tis\tfree" | tr '\t' ' '
# 输出:linux is free

示例:用八进制\012表示换行(等价于\n)

echo "linux is free" | tr ' ' '\012'
# 输出:linux
# is
# free

3. 字符范围:M-N

M-N表示从字符M到字符N的连续字符,按ASCII码升序排列,适用于连续字符的场景,例如:

  • 0-9:所有数字
  • a-z:所有小写字母
  • A-Z:所有大写字母
  • a-Z:所有大小写字母(部分系统支持)

示例:小写字母转大写字母

echo "hello linux" | tr 'a-z' 'A-Z'
# 输出:HELLO LINUX

注意:字符范围仅在Clocale下可移植,EBCDIC编码的系统中A-Z并非连续,建议优先用字符类(下文)。

4. 重复字符:[CN] / [C]

仅在STRING2中生效,用于快速生成重复的字符,避免手动输入多次:

  • [C*N]:生成N个字符C(N为数字,0开头表示八进制,0值则忽略);
  • [C*]:将C重复,补齐到和STRING1相同的长度。

示例1:生成6个y,替换数字0-9为y([y*6]仅前6个数字替换为y,后4个按GNU默认规则也替换为y)

echo "1234567890" | tr '0-9' '[y*6]'
# 输出:yyyyyyyyyy

示例2:将所有非字母的字符替换为换行(用[\n*]自动补齐补集长度)

echo "linux123is@free" | tr -c 'a-z' '[\n*]'
# 输出:linux
# is
# free

5. 预定义字符类:[:CLASS:]

最推荐的方式,可移植性最高,用[:CLASS:]表示一类字符,注意前后的冒号不能少,核心字符类如下(必记):
| 字符类 | 含义 | 字符类 | 含义 |
|----------|----------------------|----------|----------------------|
| [:alnum:]| 字母+数字 | [:digit:]| 数字0-9 |
| [:alpha:]| 大小写字母 | [:lower:]| 小写字母a-z |
| [:blank:]| 水平空白(空格+Tab) | [:upper:]| 大写字母A-Z |
| [:space:]| 所有空白(含换行/回车)| [:punct:]| 所有标点符号 |
| [:cntrl:]| 所有控制字符 | [:print:]| 可打印字符(含空格) |
| [:graph:]| 可打印字符(不含空格)| [:xdigit:]| 十六进制数字 |

核心规则

  • 仅删除/压缩时,字符类可在STRING1/STRING2任意位置;
  • 字符翻译时,仅[:lower:][:upper:]可在STRING2中使用,且需和STRING1的对应类位置一致(用于大小写转换)。

示例1:用字符类实现小写转大写(最便携)

echo "hello LINUX" | tr '[:lower:]' '[:upper:]'
# 输出:HELLO LINUX

示例2:删除所有标点符号

echo "hello! linux, how are you?" | tr -d '[:punct:]'
# 输出:hello linux how are you

6. 等价类:[=C=]

基本无实用价值,本意是表示和字符C等价的所有字符(适配非英语字母),但GNU tr中每个字符的等价类只有自己,因此几乎不用,了解即可。

四、tr经典实用场景(组合用法)

tr的强大之处在于选项组合+字符集灵活搭配,下面讲解日常工作中最常用的场景,覆盖翻译、删除、压缩的各种组合,直接抄作业即可。

场景1:大小写转换(最常用)

三种实现方式,推荐第三种字符类方式,可移植性最高:

# 方式1:手动写字母
echo "Hello Linux" | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
# 方式2:字符范围
echo "Hello Linux" | tr 'a-z' 'A-Z'
# 方式3:字符类(推荐)
echo "Hello Linux" | tr '[:lower:]' '[:upper:]'

# 大写转小写,反向即可
echo "Hello Linux" | tr '[:upper:]' '[:lower:]'

场景2:清理文本中的空行/连续换行

-s压缩连续的换行符\n,直接消除空行:

# 原始输入有连续换行,压缩为单个换行
echo -e "linux\n\n\nis\n\nfree" | tr -s '\n'
# 输出:
# linux
# is
# free

# 也可将换行压缩为空格,把多行转为一行
echo -e "linux\nis\nfree" | tr -s '\n' ' '
# 输出:linux is free

场景3:删除文本中的所有数字/字母

结合-d和字符类,精准删除指定类型字符:

# 删除所有数字
echo "linux123is456free789" | tr -d '[:digit:]'
# 输出:linuxisfree

# 删除所有字母
echo "linux123is456free789" | tr -d '[:alpha:]'
# 输出:123456789

场景4:将所有非字母/数字的字符替换为换行

结合-c(补集)和-s(压缩),实现“按字母/数字分割行”,适合提取文本中的关键词:

# 非字母数字替换为换行,再压缩连续换行
echo "linux!123is@free#os" | tr -cs '[:alnum:]' '[\n*]'
# 输出:
# linux
# 123
# is
# free
# os

场景5:删除文本中的控制字符/特殊字符

Linux文本文件中常出现^M(\r)等Windows控制字符,用tr快速删除:

# 删除回车符\r(解决Windows文件在Linux中的换行问题)
cat test.txt | tr -d '\r' > new_test.txt

# 删除所有控制字符
cat test.txt | tr -d '[:cntrl:]' > new_test.txt

场景6:统计文本中单词的重复次数

结合tr和uniq,先将文本处理为“一行一个单词”,再统计重复项,这是tr在脚本中的经典用法:

# 脚本实现:提取重复单词,忽略大小写和标点
cat text.txt \
| tr -s '[:punct:][:blank:]' '[\n*]' \  # 标点/空白替换为换行,压缩连续换行
| tr '[:upper:]' '[:lower:]' \            # 全部转为小写
| uniq -d                                 # 仅显示重复的行(重复单词)

场景7:批量替换指定字符(多字符替换)

tr支持多字符一对一翻译,按字符集的顺序依次替换:

# 将a→1,b→2,c→3
echo "abcabc123" | tr 'abc' '123'
# 输出:123123123

# 将空格→_,Tab→-
echo "linux is\tfree" | tr ' \t' '_-'
# 输出:linux_is-free

五、tr使用的注意事项(避坑点)

  1. tr不支持多字节字符:UTF-8中的中文、特殊字母(ö、Ł)等多字节字符,tr会按单字节解析,导致乱码,处理多字节字符建议用sed/awk
  2. 字符范围的可移植性a-z/A-Z仅在Clocale下有效,跨系统建议用[:lower:]/[:upper:]
  3. 连字符-的处理:若要处理-本身,需将其放在字符集最后,或用--终止选项解析:
    # 正确删除-:放在最后
    echo "linux-123-os" | tr -d '0-9-'
    # 正确删除-:用--终止选项
    echo "linux-123-os" | tr -d -- '-0-9'
    
  4. STRING1重复字符的处理:若STRING1中有重复字符,GNU tr会取最后一个作为有效映射:
    # a出现3次,取最后一个,a→z
    echo "abc" | tr 'aaa' 'xyz'
    # 输出:zbc
    
  5. tr是按字符处理,非按字符串:tr只能处理单个字符,无法替换多字符的字符串,替换字符串建议用sed

六、tr的退出状态

  • 0:执行成功,无错误;
  • 非0:执行失败(如选项错误、字符集格式错误、输入流异常等)。

日常工作中,tr常和echo/cat/uniq/sort等命令配合使用,在文本快速处理、shell脚本中能大幅提升效率,熟记本文的经典示例,即可解决90%的字符处理需求。

相关文章
|
安全 Linux 网络安全
组网神器WireGuard安装与配置教程(超详细)
组网神器WireGuard安装与配置教程(超详细)
67855 2
|
6月前
|
人工智能 API 机器人
OpenClaw 用户部署和使用指南汇总
本文档为OpenClaw(原MoltBot)官方使用指南,涵盖一键部署(阿里云轻量服务器年仅68元)、钉钉/飞书/企微等多平台AI员工搭建、典型场景实践及高频问题FAQ。同步更新产品化修复进展,助力用户高效落地7×24小时主动执行AI助手。
30508 253
|
3月前
|
资源调度 运维 监控
Flink on YARN 多 Session 集群能力:让小任务共享大资源,实现实时计算降本增效
Dataphin推出FlinkonYARN多Session集群能力,支持小任务共享资源池、多业务隔离及秒级提交,显著降低实时计算资源消耗与运维成本。
184 3
|
6月前
|
域名解析 缓存 网络协议
Linux dnsmasq完全教程
dnsmasq是轻量级DNS+DHCP一体化工具,专为小型局域网设计。它能实现DNS缓存加速、内网域名解析(如用“server.local”代替IP)、自动分配IP地址,配置简单、资源占用低,树莓派或老旧服务器也能流畅运行,是家庭、工作室网络管理的“全能小管家”。
|
7月前
|
网络协议 Linux 网络安全
Rocky Linux 下 DHCP 服务配置详细文档
DHCP(动态主机配置协议)是局域网中用于自动分配IP地址、网关、DNS等网络参数的核心协议,工作于UDP 67/68端口。通过“发现-提供-请求-确认”四步租约机制,实现客户端即插即用,提升IP利用率。支持固定IP绑定、跨子网中继及多网段超级作用域配置,广泛应用于各类网络环境。
|
SQL 存储 大数据
Flink 基础详解:大数据处理的强大引擎
Apache Flink 是一个分布式流批一体化的开源平台,专为大规模数据处理设计。它支持实时流处理和批处理,具有高吞吐量、低延迟特性。Flink 提供统一的编程抽象,简化大数据应用开发,并在流处理方面表现卓越,广泛应用于实时监控、金融交易分析等场景。其架构包括 JobManager、TaskManager 和 Client,支持并行度、水位线、时间语义等基础属性。Flink 还提供了丰富的算子、状态管理和容错机制,如检查点和 Savepoint,确保作业的可靠性和一致性。此外,Flink 支持 SQL 查询和 CDC 功能,实现实时数据捕获与同步,广泛应用于数据仓库和实时数据分析领域。
11502 42
|
缓存 Ubuntu Linux
Docker Buildx 简介与安装指南
Docker Buildx 是一个强大的工具,提供了多架构构建、并行构建和高级缓存管理等功能。通过正确安装和配置 Buildx,可以显著提升 Docker 镜像的构建效率和灵活性。希望本文能帮助你更好地理解和使用 Docker Buildx,以提高开发和部署的效率。
7558 16
|
Linux 数据处理
Linux中sort命令详解
Linux中sort命令详解
|
安全 Java API
【Java性能优化】Map.merge()方法:告别繁琐判空,3行代码搞定统计累加!
在日常开发中,我们经常需要对Map中的值进行累加统计。}else{代码冗长,重复调用get()方法需要显式处理null值非原子操作,多线程下不安全今天要介绍的方法,可以让你用一行代码优雅解决所有这些问题!方法的基本用法和优势与传统写法的对比分析多线程安全版本的实现Stream API的终极优化方案底层实现原理和性能优化建议一句话总结是Java 8为我们提供的Map操作利器,能让你的统计代码更简洁、更安全、更高效!// 合并两个列表});简单累加。
1201 0
|
存储 NoSQL Linux
linux之core文件如何查看和调试
通过设置和生成 core 文件,可以在程序崩溃时获取详细的调试信息。结合 GDB 等调试工具,可以深入分析 core 文件,找到程序崩溃的具体原因,并进行相应的修复。掌握这些调试技巧,对于提高程序的稳定性和可靠性具有重要意义。
8305 6