在 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
)。他們也可以選擇僅轉換初始的、前導的空格/製表符。有關詳細信息,請參閱手冊頁。
有關 的更多信息sponge
,請參閱man sponge
和是否有標準的替代海綿來將文件傳輸到自身?。簡而言之,它使用臨時檔案為您執行重定向和 mv。順便說一句,永遠不要嘗試將標準輸出重定向到目前用作標準輸入的相同檔案。 shell 會在讀取之前覆蓋它。
sponge
是來自更多實用程式包裹。
PS:另請參閱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