インデントされたタブをタブごとに固定数のスペースで置き換える

インデントされたタブをタブごとに固定数のスペースで置き換える

「先行タブ」をタブごとに特定の数のスペースに置き換えることはできますか?私は前にタブまたはスペースのみを持つタブを前のタブとして定義します。私は先行タブまたはインデントタブを前に空白のみのタブとして定義します。

私の次の行は.nexrc次からコピーされました。これ。タグを含む行aとタグの間の行でフィルタを通過します。bタブを置き換えます。

map \2 'a!'b pr -te2

しかし、先行しないタブ文字を2つのスペースに置き換える作業は素晴らしいです。時にはリテラルタブ文字が必要なので理想的ではありません。

先行タブのみタブごとに特定の数のスペースに置き換える簡単で移植可能な方法はありますか?

以下のPerlスクリプト(1行に縮小可能)は、前のタブ文字をコマンドラインで指定された幅に置き換えますが、Perlの可用性に依存し、2次時間がかかります(ファイルに何も含まれていない場合)。しかし、タブ)。

#!/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'

上記のコマンドは、2番目のパラメータで1Tabつ以上のエントリを単一のスペースに置き換えます。必要なスペースを作成して構成可能にすることができます。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

関連情報