vim では次のように実行できるようです:
:s/^\t\+/\=repeat(' ',len(submatch(0)))
これが sed にどのように変換されるかわかりませんでした。次のことを試しました:
sed -ri "s/^\t\+/\=repeat(' ',len(submatch(0)))/g" test.txt
コマンドは効果がないようです。
答え1
これはexpand
、例えば のためですexpand -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
)。先頭のスペース/タブのみを変換するオプションもあります。詳細については、man ページを参照してください。
の詳細についてはsponge
、man sponge
およびを参照してください。ファイルをそれ自身にパイプするための、sponge の標準的な代替手段はありますか?つまり、一時ファイルを使用してリダイレクトと mv を実行します。ちなみに、stdout を現在 stdin として使用されている同じファイルにリダイレクトしないでください。シェルは、読み取られる前にそれを上書きします。
sponge
はもっと見るパッケージ。
追記:こちらもご覧くださいGNUインデントまたは、他の多くの同様のソースコード再フォーマット ツールのいずれか。
答え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