将缩进选项卡替换为每个选项卡固定数量的空格

将缩进选项卡替换为每个选项卡固定数量的空格

是否可以仅用每个选项卡的一定数量的空格替换“前导选项卡”?我将前导制表符定义为前面仅包含制表符或空格的制表符。我将前导或缩进制表符定义为仅前面有空格的制表符。

我的以下行.nexrc抄袭自这个。它通过过滤器运行包含标记的行a和标记之间的行。b取代选项卡。

map \2 'a!'b pr -te2

但是,它很好地用两个空格替换了非前导制表符,这并不理想,因为有时需要文字制表符。

是否有一种简单且可移植的方法来仅用每个选项卡一定数量的空格替换前导选项卡?

下面的 perl 脚本(可以折叠为一行)的工作是用命令行上提供的宽度替换前导制表符,但它依赖于 Perl 的可用性,并且需要二次时间(如果文件不包含任何内容)但选项卡)。

#!/usr/bin/env perl

use strict;
use warnings;

my ($width) = @ARGV;
$width //= 2;
my $replacement = ' ' x $width;

while (<>) {
    while (s/^(\s*)\t/$1$replacement/g) { }
    print;
}

这是我想要发生的事情的一个例子。^I指制表符字节,#是行开头的零宽度标记。下面的行是字节标尺。

前:

#^I^I ^Ia^Ib
# 1 23 45 67

之后(制表符宽度为 2)

#       a^Ib
#12345678 90

之后(制表符宽度为 4)

#             a^Ib
#12345678901234 56

答案1

如果您正在寻找使用其他命令行工具的通用解决方案,可以使用Awk此工具。

var=$'\t\t\tnewcontent'
echo "$var" | awk '{ gsub(/^[\t]+/," ",$0) }1'

上面的命令将再出现一次 替换为Tab单个空格,即 中的第二参数gsub。您可以通过生成所需的空间数量来使其可配置

awk -v n=5 ' BEGIN{ spaces = sprintf("%"n"s"," ") }{ gsub(/^[\t]+/,spaces,$0) }1'

从上次更新来看,OP似乎想用找到的确切空格数替换前导制表符的数量,

awk -F$'\t' '{ spaces = sprintf("%"(NF-1)"s"," "); gsub(/^[\t]+/,spaces,$0) }1'

逻辑是通过将字段分隔符设置为\t,可以通过执行来识别前导制表符的数量NF-1。确定前导制表符的数量后,使用它来生成与早期sprintf()方法相同数量的空格。

验证hexdump -C更换前后就可以看到

echo "$var" | hexdump -C
00000000  09 09 09 6e 65 77 63 6f  6e 74 65 6e 74 0a        |...newcontent.|
0000000e

现在更换

echo "$var" | awk -F$'\t' '{ spaces = sprintf("%"(NF-1)"s"," "); gsub(/^[\t]+/,spaces,$0) }1' | hexdump -C
00000000  20 20 20 6e 65 77 63 6f  6e 74 65 6e 74 0a        |   newcontent.|
0000000e

相关内容