tr的使用

本文详细介绍了tr命令的工作原理、使用实例及注意事项,包括字符替换、文件间隔符修改、大小写转换等功能,帮助您掌握Linux环境下文本处理技巧。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本原创文章属于《Linux大棚》博客,博客地址为http://roclinux.cn。文章作者为rocrocket。

为了防止某些网站的恶性转载,特在每篇文章前加入此信息,还望读者体谅。

===

[正文开始]

tr是translate的简写,亦即翻译,但是遗憾的是,它不能翻译句子,只能翻译单个字符。

1 tr的工作原理是什么?

先记住一点,tr命令不接受指定的文件参数,而只是对标准输入进行翻译。好了,记住这点后,我们继续。

tr的命令格式是tr SET1 SET2,凡是在SET1中的字符,都会被替换为SET2中相应位置上的字符,简单吧!

2 举个例子吧!

tr的例子其实都大同小异,看一个最简单的例子:

我们有一个包含了四个人身高的数据文件,名字叫height.txt,它的内容是这样的:

[rocrocket@rocrocket programming]$ cat height.txt
1.79 1.83
1.65 1.59

我们想搞一个恶作剧,将所有人的身高从1米级别都提高到2米级别,呵呵,一个tr就可以搞定。
[rocrocket@rocrocket programming]$ tr 1 2 < height.txt
2.79 2.83
2.65 2.59

希望你没有忘记,tr只处理标准输入,所以我们需要将height.txt通过重定向指到tr的标准输入才可以。

3 我们可以用tr来修改文件中的间隔符么?

Good idea!

当使用cut的时候,通常会被间隔符问题所困扰,我们这个时候可以考虑到tr这个命令。

还是以height.txt文件为例,其中的间隔符是空格,我们把它修改为制表符吧!

[rocrocket@rocrocket programming]$ tr ‘ ‘ ‘\11′ < height.txt
1.79    1.83
1.65    1.59

这里有一个小知识点,像制表符、换行符这些字符不好表示,我们可以考虑使用ASCII的八进制形式来表示,制表符的八进制形式是11,回车是15,换行是12。而在tr命令中,可以使用\nnn形式表示八进制形式的字符。如果你实在记不住这些编号,那么用\t表示制表符你总该可以记住吧!(\n代表新行,\r代表回车)

这下,你应该可以理解上面那条命令的作用了吧。如果你仍然怀疑,那么,看看下面这条命令,你就该心服口服了:

[rocrocket@rocrocket programming]$ tr ‘ ‘ ‘\11′ < height.txt |sed -n l
1.79\t1.83$
1.65\t1.59$

看!空格的的确确被替换成了制表符喽!

4 使用tr能把文章中的小写都转换成大写么?

这个正是tr所擅长的地方。

加入我们拥有一个文件叫做word.txt,里面包含的内容是AbcdE。

那么最简单的替换大小写的方法是:

[rocrocket@rocrocket programming]$ cat word.txt
AbcdE
[rocrocket@rocrocket programming]$ tr ‘a-z’ ‘A-Z’ < word.txt
ABCDE

5 [CHAR*]怎么用?

这是 SET2 专用的设定,功能是重复指定的字符到与 SET1 相同长度为止

例子:

[rocrocket@rocrocket programming]$ cat number.txt
1234567890
[rocrocket@rocrocket programming]$ tr ‘1-5′ ‘[A*]‘ < number.txt
AAAAA67890

6 [CHAR*REPEAT]怎么用?

这也是SET2专用的设定,功能是将CHAR重复REPEAT次数。其中REPEAT次数可以用八进制数表示,但记得要以0开头表示八进制数。

例子:

[rocrocket@rocrocket programming]$ tr ‘1-9′ ‘[A*5]BCDE’ < number.txt
AAAAABCDE0

7 在tr中还有哪些表示集合的符号呢?

[:alnum:] :所有字母字符与数字
[:alpha:] :所有字母字符
[:blank:] :所有水平空格
[:cntrl:] :所有控制字符
[:digit:] :所有数字
[:graph:] :所有可打印的字符(不包含空格符)
[:lower:] :所有小写字母
[:print:] :所有可打印的字符(包含空格符)
[:punct:] :所有标点字符
[:space:] :所有水平与垂直空格符
[:upper:] :所有大写字母
[:xdigit:] :所有 16 进位制的数字

例子:

将所有的数字都转换为字符x。

[rocrocket@rocrocket programming]$ tr [:alnum:] ‘[x*]‘ < number.txt
xxxxxxxxxx

8 tr里面包含SET1和SET2,那如果出现两个集合的大小不同的情况,tr如何处理呢?

这个问题,最好的解决办法就是做实验啊。

第一种情况是SET1>SET2:

[rocrocket@rocrocket programming]$ tr 1-5 AB < number.txt
ABBBB67890

结论一下子就出来了,SET1中多出来的字符都会和SET2中最后一个字符相对应。

第二种情况SET1<SET2:

[rocrocket@rocrocket programming]$ tr 1-3 ABCDE < number.txt
ABC4567890

很明了,SET2中多余的部分将被抛弃。

9 讲一讲tr命令的-s选项吧!

这个-s选项,是专门针对SET1起作用的,意思是如果发现有连续的SET1里的字符,就把它们缩减为1个。

一个很经典的应用就是把不规律的空格缩减为一个空格:

[rocrocket@rocrocket programming]$ cat spaces.txt
How   are               you?
Fine! Thank    you!
[rocrocket@rocrocket programming]$ tr -s ‘ ‘ ‘ ‘ < spaces.txt
How are you?
Fine! Thank you!

效果很明显,用户很满意。恩!

10 -d选项咋用?

-d选项是用来删除字符用的。格式是这样的:tr -d charset

[rocrocket@rocrocket programming]$ tr -d ‘ ‘ < spaces.txt
Howareyou?
Fine!Thankyou!

看,该有的空格都没了…这就是-d的作用,把空格都删除了!

如果你想把文章中的数字都删除,就tr -d [0-9] < filename就可以了。

 Translation occurs if -d is not given and both SET1  and  SET2  appear.
       -t  may  be  used only when translating.  SET2 is extended to length of
       SET1 by repeating its last character as necessary.   Excess  characters
       of  SET2  are  ignored.  Only [:lower:] and [:upper:] are guaranteed to
       expand in ascending order; used in SET2  while  translating,  they  may
       only  be used in pairs to specify case conversion.  -s uses SET1 if not
       translating nor deleting; else squeezing uses  SET2  and  occurs  after
       translation or deletion. 

-d 选项不需要 SET1 和SET2.但是-t需要。SET2扩展到SET1的长度通过重复它的最后一个字符(SET1长于SET2),超过的字符忽略(SET2长于SET1).[:lower:] and [:upper:] 同时使用用于大小写转换。



ps: 看似tr只有两个字母,不过这个命令的功能却不少,可不能小觑,不过,读过本文,搞定tr也就不在话下了:D

over~

<think>好的,我需要回答用户关于如何在Qt中正确使用TR函数进行国际化处理的问题。首先,我得回忆一下Qt的国际化机制,特别是tr()函数的作用和使用方法。根据用户提供的引用内容,tr()函数用于标记需要翻译的文本,然后通过生成.ts文件,使用Qt Linguist进行翻译,最后生成.qm文件供应用程序加载。 首先,应该分步骤说明如何使用tr()函数。第一步是在代码中用tr()包裹所有用户可见的字符串,例如按钮的文本或标签。这时候需要确保所有字符串都是通过tr()传递的,比如`button.setText(tr("Submit"))`。同时要注意,tr()是QObject的成员函数,所以如果是在非QObject子类中使用,可能需要使用Q_DECLARE_TR_FUNCTIONS宏来声明,或者使用QCoreApplication::translate()函数。 接下来,需要说明如何生成翻译文件。用户提到使用lupdate工具提取源代码中的tr()字符串,生成.ts文件。这通常是通过在.pro文件中添加TRANSLATIONS += myapp_zh_CN.ts,然后运行lupdate命令。之后,用Qt Linguist打开.ts文件进行翻译,填写对应的目标语言字符串。完成后,使用lrelease将.ts文件编译成.qm文件。 然后,在应用程序启动时加载.qm文件。这部分需要说明如何使用QTranslator加载翻译文件,并安装到应用程序中。例如: QTranslator translator; if (translator.load("myapp_zh_CN.qm", ":/i18n")) { app.installTranslator(&translator); } 此外,需要注意的一些常见问题,比如动态字符串的处理,可能需要使用arg()方法进行参数替换,或者使用QT_TR_NOOP宏标记在数组中的字符串。还有上下文的问题,tr()函数的上下文默认是类名,但有时候可能需要指定不同的上下文,这时候可以使用QCoreApplication::translate()函数并明确指定上下文。 还要提到在非QObject派生类中使用tr()的情况,比如全局函数或静态类,需要使用Q_DECLARE_TR_FUNCTIONS来添加tr()的支持。此外,在QML中使用qsTr()而不是tr(),这也是Qt国际化的另一个部分,但用户的问题可能集中在C++部分。 最后,应该提醒用户确保在.pro文件中启用翻译支持,比如添加CONFIG += console,但可能不需要,具体取决于项目配置。同时,在代码中正确包含必要的头文件,如QTranslator和QApplication。 可能还需要提到测试翻译的方法,比如切换应用程序的语言环境,或者动态重新加载翻译文件。此外,处理复数形式可能需要使用tr()的复数形式参数,例如`tr("%n item(s)", "", count)`,这样Qt Linguist可以正确处理不同数量的复数形式。 总结下来,步骤大致分为:标记字符串、生成翻译文件、翻译、编译和加载翻译文件。同时需要注意上下文、动态字符串、非QObject类的使用,以及测试和复数处理等问题。根据用户提供的引用,尤其是引用[1][2][3][4],需要将这些内容整合成一个结构清晰的回答,并生成相关问题。</think>在Qt中使用`tr()`函数进行国际化处理需要遵循以下步骤: ### 一、标记可翻译文本 1. **在代码中使用`tr()`包裹字符串** 所有用户可见的文本(如按钮标签、窗口标题等)必须用`tr()`标记。例如: ```cpp QPushButton *button = new QPushButton(tr("Submit")); // 标记按钮文本为可翻译 ``` - **注意**:`tr()`是`QObject`的成员函数。若在非`QObject`派生类(如工具类)中使用,需通过宏`Q_DECLARE_TR_FUNCTIONS`声明支持[^3]。 2. **处理动态字符串** 若字符串包含动态内容(如变量),使用`QString::arg()`占位: ```cpp QString message = tr("File %1 not found").arg(fileName); // 动态插入文件名 ``` --- ### 二、生成翻译文件 1. **配置.pro文件** 在Qt项目文件(.pro)中添加翻译文件路径: ```pro TRANSLATIONS += myapp_zh_CN.ts # 中文翻译文件 ``` 2. **提取可翻译文本** 运行`lupdate`工具扫描代码中的`tr()`字符串并生成.ts文件: ```bash lupdate project.pro # 生成或更新.ts文件 ``` --- ### 三、翻译文本 1. **使用Qt Linguist编辑.ts文件** 打开.ts文件,逐条填写目标语言翻译(如中文): - 若未安装Linguist,可通过Qt Creator菜单操作:**工具 → 外部 → Qt语言家 → 更新翻译**[^4]。 2. **编译为.qm文件** 翻译完成后,使用`lrelease`将.ts文件编译为二进制.qm文件: ```bash lrelease project.pro # 生成.qm文件 ``` --- ### 四、加载翻译文件 在应用程序启动时加载.qm文件: ```cpp #include <QTranslator> #include <QApplication> int main(int argc, char *argv[]) { QApplication app(argc, argv); QTranslator translator; if (translator.load("myapp_zh_CN.qm", ":/i18n")) { // 从资源文件加载 app.installTranslator(&translator); // 安装翻译器 } // 创建主窗口并显示 return app.exec(); } ``` --- ### 常见问题与解决 1. **翻译未生效** - 检查.qm文件路径是否正确。 - 确保`QTranslator`对象在`QApplication`之后创建[^1]。 2. **处理复数形式** 使用`tr()`的复数参数: ```cpp tr("%n item(s)", "", itemCount); // 根据itemCount自动选择单复数形式 ``` 3. **非界面类翻译** 在静态工具类中使用`QT_TR_NOOP`宏标记字符串,后续通过`tr()`引用: ```cpp const char *messages[] = { QT_TR_NOOP("Hello"), QT_TR_NOOP("World") }; QString text = tr(messages[0]); // 实际翻译 ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值