sedを使用して先行タブ文字を4つのスペースに置き換える方法は?

sedを使用して先行タブ文字を4つのスペースに置き換える方法は?

vimではこれを行うことができるようです。

:s/^\t\+/\=repeat('    ',len(submatch(0)))

これがsedにどのように変換されるかわかりません。私は以下を試しました:

sed -ri "s/^\t\+/\=repeat('    ',len(submatch(0)))/g" test.txt

このコマンドは効果がないようです。

答え1

たとえば、次のようになりますexpandexpand -t 4 file.txt

expandソースファイルは編集されませんが、新しいファイルにリダイレクトしてmvソースを上書きするか、インストールされてspongeいる場合に使用できます。

    expand -t 4 file.txt > file.new && mv file.new file.txt
or 
    expand -t 4 file.txt | sponge file.txt

参考までに、unexpand逆に複数のスペースをタブに変換するをご覧ください。

expand両方とも、unexpand固定幅タブ文字(たとえば、-t 4など-t 8)の使用をサポートします。またはタブ位置のリスト(たとえば-t 4,12,32)も、最初の先行スペース/タブのみを変換することを選択できます。詳しくはマニュアルページをご覧ください。


詳細については、以下をsponge参照してくださいman spongeファイルを独自に転送するためのスポンジの標準的な代替案はありますか?。つまり、一時ファイルを使用してリダイレクトとmvを実行します。ただし、標準出力を現在の標準入力として使用されているのと同じファイルにリダイレクトしないでください。シェルは読み取り前にそれを上書きします。

sponge出身ですその他のユーティリティパック。


PS:また参照してくださいGNUインデントまたは他の同様のソースコード書式設定ツールの1つです。

答え2

$ cat -T /tmp/test.txt
^I^I^I3^I<= this final tab should remain
^I^I2
^I1

sedを使用してください:

sed ':loop;s/^\( *\)\t/\1    /;tloop' /tmp/test.txt | cat -T
            3^I<= this final tab should remain
        2
    1

上記は、すべての先行スペースと先行タブをキャプチャし、成功すると()loopタブを4つの空白に変換するループ(通常はラベル付き)を設定します。tバラよりhttps://stackoverflow.com/a/35017207/493161

関連情報