制表符记录的是移动到制表位的操作,而不是固定数量的可见空格。它显示出的宽度取决于当前列和制表位设置。expand 和 unexpand 命令会根据这些位置,在制表符和空格之间进行转换。
文本操作 · 第 10 课
expand 和 unexpand
学习制表位如何控制 expand 和 unexpand 在制表符与空格之间进行转换。
将制表符转换为空格
expand 读取输入,把制表符替换为到达相应制表位所需的空格,然后将结果写入 stdout:
$ expand sample.txt
默认情况下,制表位每隔 8 列出现一次。因此,位于第 1 列的制表符与位于第 6 列的制表符会展开成不同数量的空格;它并非总是替换为八个空格。
使用默认设置时,expand 如何替换一个制表符?
选择制表位
使用 -t NUMBER 可按指定的列间隔设置制表位。若要每四列设置一个制表位:
$ expand -t 4 sample.txt
GNU expand 也接受以逗号分隔的明确制表位列表。如果只想转换每行第一个非空白字符之前的制表符,请使用 -i。
哪个命令会使用每四列一个的制表位来转换制表符?
安全保存转换结果
expand 不会编辑输入文件。需要保存转换后的文本时,请将 stdout 重定向到另一个路径:
$ expand sample.txt > result.txt
不要使用 expand sample.txt > sample.txt。shell 会在 expand 读取文件之前截断目标文件,因而可能丢失源数据。确认另行写出的结果正确后,再通过适当的文件管理操作有意替换原文件。
哪个命令能保存展开后的文本,又不会在读取 sample.txt 之前将其截断?
将空格转换为制表符
unexpand 会把符合条件的空格替换为制表符,同时保持它们在所选制表位上的对齐。默认情况下,GNU unexpand 只转换每行第一个非空白字符之前的行首空白:
$ unexpand result.txt
使用 -a 可让命令检查每行各处符合条件的空白:
$ unexpand -a result.txt
这并不是简单地把每一串八个空格都替换掉。和 expand 一样,转换取决于列位置和制表位。如果文件采用其他约定,请使用 -t 4 或其他制表位设置。
不使用 -a 时,GNU unexpand 通常会考虑转换哪些空格?
哪个选项会让 GNU unexpand 也考虑第一个非空白字符之后的空白?
未指定文件时,这两个命令都会读取 stdin,因此可以在管道中使用。请记住,即使显示出的对齐方式没有变化,先转换为空格再转回制表符,也不一定能还原原本对制表符和空格的选择。
课程已完成
你已完成 expand 和 unexpand
现在,你可以在保持制表位对齐的同时转换制表符和空格。
将制表符展开到下一个配置好的制表位。
使用
-t设置自定义制表位。先把输出保存到另一个文件,再替换输入文件。
默认使用
unexpand转换行首空白。需要考虑每行各处的空白时使用
-a。