如何使用grep或sed用制表符替换前导空格?

时间:2016-01-26 11:28:32

标签: macos sed grep

我想使用grep或sed替换文件中每行的等量选项卡的所有前导空格字符。每行都有一些空格,后跟一个破折号和一些文字。

 -Line 1  
  -Line 2  
   -Line 3

找到它们不是问题,但我没有看到如何使用反向引用替换这些字符。类似的东西:

sed 's/^([\s]+)(-.*)/\1\2/' file.txt

我该如何解决这个问题?或者甚至可能吗?

2 个答案:

答案 0 :(得分:1)

根据您的标签宽度,您可能希望用标签替换例如4或8个空格的块,例如

sed 's/^ \{4\}/\t/g' infile

sed 's/^ \{8\}/\t/g' infile

这会打开一个看起来像

的文件
$ cat infile
no space
 1 space
  2 spaces
   3 spaces
    4 spaces
     5 spaces
      6 spaces
       7 spaces
        8 spaces
         9 spaces
          10 spaces
           11 spaces

到此处(用^I替换标签,以便我们可以看到它们):

$ sed 's/^ \{4\}/\t/g' infile | cat -T
no space
 1 space
  2 spaces
   3 spaces
^I4 spaces
^I 5 spaces
^I  6 spaces
^I   7 spaces
^I^I8 spaces
^I^I 9 spaces
^I^I  10 spaces
^I^I   11 spaces

或者

$ sed 's/ \{8\}/\t/g' infile | cat -T
no space
 1 space
  2 spaces
   3 spaces
    4 spaces
     5 spaces
      6 spaces
       7 spaces
^I8 spaces
^I 9 spaces
^I  10 spaces
^I   11 spaces

标签宽度可以参数化(注意双引号):

$ tw=7
$ sed "s/ \{$tw\}/\t/g" infile | cat -T
no space
 1 space
  2 spaces
   3 spaces
    4 spaces
     5 spaces
      6 spaces
^I7 spaces
^I 8 spaces
^I  9 spaces
^I   10 spaces
^I    11 spaces

请注意如何在vim中轻松完成此操作,请参阅this question

仅在行首

处的空格

上面的命令用选项卡替换任意组的四个或八个空格。如果你只想在一行的开头替换空格,比如这样的文件:

$ cat infile 
    4 spaces    word
     5 spaces    word
      6 spaces    word
       7 spaces    word
        8 spaces    word 
         9 spaces    word

你可以使用

$ sed ':a;s/^\(\t*\) \{4\}/\1\t/;/^\t* \{4\}/ba' infile | cat -T
^I4 spaces    word
^I 5 spaces    word
^I  6 spaces    word
^I   7 spaces    word
^I^I8 spaces    word 
^I^I 9 spaces    word

这是做什么的:

# Label to branch to
:a

# Replace optional leading tabs followed by four spaces
# by the same amount plus one tabs
s/^\(\t*\) \{4\}/\1\t/

# If there are still four spaces after leading tabs, branch to a
/^\t* \{4\}/ba

更新

原来问题实际上是关于用行标签替换行开头的空格。

对于此输入

0 spaces
 1 space
  2 spaces
   3 spaces

以下sed命令有效:

$ sed ':a;s/^\(\t*\) /\1\t/;ta' infile | cat -T
0 spaces$
^I1 space$
^I^I2 spaces$
^I^I^I3 spaces$

说明:

:a                # Label to branch to
s/^\(\t*\) /\1\t/ # Capture tabs at start of line, replace next space with tab
ta                # Branches to :a if there was a substitution

答案 1 :(得分:0)

保持简单,只需使用awk:

$ awk '{s=$0; sub(/[^ ].*/,"",s); gsub(/ /,"\t",s); sub(/^ +/,s)} 1' file
        -Line 1
                -Line 2
                        -Line 3