根据您的制表符宽度,您可能希望用制表符替换例如 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。
仅在行首有空格
上面的命令用制表符替换 any 四个或八个空格的组。如果你只想替换行首的空格,比如这样的文件:
$ 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