将文件的缩进从制表符转换为空格

时间:2014-01-11 07:48:30

标签: vim sed awk indentation

将制表符缩进文件转换为空格缩进文件的最佳方法是什么?

我希望能够为每个标签替换指定可变数量的空格。

换句话说,在以连续序列标签开头的每一行中,我想用X空格替换序列的每个标签,在那里我设置X.

我不介意使用什么工具,无论是AWK,sed还是Vim。

任何人都知道最好的方法是什么?

更新/意译/澄清:

换句话说,这是我需要运行文件的过程:

“在每一行上,用3个空格替换该行上第一个非制表符前面的每个制表符”

6 个答案:

答案 0 :(得分:5)

Linux或许多Unix系统上最简单的解决方案是使用expand命令。

如果使用Vi或Vim编辑文件,可以将以下内容添加到.vimrc文件中,以确保在编辑文件时标签始终扩展为空格:

set expandtab

有关Vim和标签的详细信息,请参阅Converting Tabs To Spaces

答案 1 :(得分:3)

在Vim中,您首先需要将'tabstop'设置设置为Tab应表示的所需空格数,并指示Vim扩展为空格:

:setlocal tabstop=3 expandtab

然后,您可以通过

所有(而不仅仅是缩进)标签更改为空格
:%retab

答案 2 :(得分:0)

也许VI(M)搜索&更换?用空格替换制表符会破坏列对齐...

:%s/\t/        /g

答案 3 :(得分:0)

这是一个awk。它将用空格替换制表符,如果它与nt值设置为相同的制表符:

awk  '{for (i=1;i<=NF;i++) if ($i=="\t") t++;if (t==nt) for (i=1;i<=t;i++) $i=" ";t=0}1' nt=2 FS="" OFS="" file

使用此文件:

cat file
no tab
        test 1 tab
                more 2 tab
                        even more 3 tab

nt=2,你得到:

no tab
        test 1 tab
  more 2 tab
                        even more 3 tab

替换了第二行中的两个标签

可能有些更复杂,只能在行首处查找标签。

更具可读性:

awk  '
    {
    for (i=1;i<=NF;i++) 
        if ($i=="\t")
            t++
    if (t==nt) 
        for (i=1;i<=t;i++) 
            $i=" "
    t=0
    }
    1
    ' nt=2 FS="" OFS="" file

答案 4 :(得分:0)

awk '{s="";i=1;while(substr($0,i++,1)=="\t")s=s "   ";sub(/^\t*/,s)}1'

答案 5 :(得分:0)

如果要用N个空白字符序列替换所有标签:

pr -e3 -t file

上面说“用3个空格字符替换每个标签并且不添加标题”,例如:

$ printf 'a\tb\tc\n'
a       b       c

$ printf 'a\tb\tc\n' | pr -e3 -t
a  b  c

$ printf 'a\tb\tc\n' | pr -e12 -t
a           b           c

如果您只想替换主要标签,则可以使用(“文件”中的所有空格都是标签符号):

$ cat file
a       b
        c       d
                e       f

$ awk -v nc=3 'match($0,/^\t+/){ $0=sprintf("%*s%s",nc*RLENGTH,"",substr($0,RSTART+RLENGTH)) }1' file
a       b
   c    d
      e f

$ awk -v nc=12 'match($0,/^\t+/){ $0=sprintf("%*s%s",nc*RLENGTH,"",substr($0,RSTART+RLENGTH)) }1' file
a       b
            c   d
                        e       f

所以你可以看到标签为#s:

$ cat file | tr '\t' '#'
a#b
#c#d
##e#f
$
$ awk -v nc=3 'match($0,/^\t+/){ $0=sprintf("%*s%s",nc*RLENGTH,"",substr($0,RSTART+RLENGTH)) }1' file | tr '\t' '#'
a#b
   c#d
      e#f

另外,如果您的UNIX拥有它,请查看indent命令。