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%的字符处理需求。

相关文章
|
2月前
|
人工智能 API 机器人
OpenClaw 用户部署和使用指南汇总
本文档为OpenClaw(原MoltBot)官方使用指南,涵盖一键部署(阿里云轻量服务器年仅68元)、钉钉/飞书/企微等多平台AI员工搭建、典型场景实践及高频问题FAQ。同步更新产品化修复进展,助力用户高效落地7×24小时主动执行AI助手。
25815 170
|
Linux Perl
解决脚本实现:sed -i 替换变量,变量中含有特殊转义字符的问题
解决脚本实现:sed -i 替换变量,变量中含有特殊转义字符的问题
解决脚本实现:sed -i 替换变量,变量中含有特殊转义字符的问题
|
3月前
|
存储 Linux 开发者
用pathlib替代os.path:现代Python路径操作最佳实践
本文对比Python中`os.path`与`pathlib`的路径处理方式,展示`pathlib`如何以面向对象、跨平台、易读性强的优势成为现代开发首选。涵盖路径构建、解析、文件操作、目录遍历等场景,结合实例说明其简洁性与实用性,并提供迁移策略与常见问题解答,助力开发者高效掌握现代化路径操作。
262 1
|
11月前
|
域名解析 网络协议 安全
计算机网络TCP/IP四层模型
本文介绍了TCP/IP模型的四层结构及其与OSI模型的对比。网络接口层负责物理网络接口,处理MAC地址和帧传输;网络层管理IP地址和路由选择,确保数据包准确送达;传输层提供端到端通信,支持可靠(TCP)或不可靠(UDP)传输;应用层直接面向用户,提供如HTTP、FTP等服务。此外,还详细描述了数据封装与解封装过程,以及两模型在层次划分上的差异。
2227 13
|
Linux 数据处理
Linux中sort命令详解
Linux中sort命令详解
|
11月前
|
安全 Java API
【Java性能优化】Map.merge()方法:告别繁琐判空,3行代码搞定统计累加!
在日常开发中,我们经常需要对Map中的值进行累加统计。}else{代码冗长,重复调用get()方法需要显式处理null值非原子操作,多线程下不安全今天要介绍的方法,可以让你用一行代码优雅解决所有这些问题!方法的基本用法和优势与传统写法的对比分析多线程安全版本的实现Stream API的终极优化方案底层实现原理和性能优化建议一句话总结是Java 8为我们提供的Map操作利器,能让你的统计代码更简洁、更安全、更高效!// 合并两个列表});简单累加。
1019 0
|
存储 JSON NoSQL
MongoDB常用命令
本文介绍了将文章评论数据存储到MongoDB中的操作方法,包括数据库和集合的基本操作。主要内容涵盖:选择与创建数据库(如`articledb`)、数据库删除、集合的显式与隐式创建及删除、文档的CRUD操作(插入、查询、更新、删除)。此外,还详细说明了分页查询、排序查询以及统计查询的方法,例如使用`limit()`、`skip()`实现分页,`sort()`进行排序,`count()`统计记录数。通过实例展示了如何高效管理MongoDB中的数据。
|
SQL Java 关系型数据库
Hive常见的报错信息
文章列举了Hive常见的几种报错信息,并提供了错误复现、原因分析以及相应的解决方案。
2061 1
|
API Android开发
Android Framework增加API 报错 Missing nullability on parameter
Android Framework增加API 报错 Missing nullability on parameter
840 1