如何使用 sed 將前導製表符替換為 4 個空格?

如何使用 sed 將前導製表符替換為 4 個空格?

在 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

相關內容