sed将4个空格转换为2


14

如何将4个空格转换为2个空格sed?可能吗?

我发现了这一点,但是它将制表符转换为空格:

sed -r ':f; s|^(\t*)\s{4}|\1\t|g; t f' file

Answers:


13

您发布的脚本将4 * n个空格转换为n个制表符,只有这些空格前面仅带有制表符时才如此。

如果您想用2个空格替换4个空格,但只能以缩进形式替换,尽管可以用sed代替,但我建议使用Perl。

perl -pe 's{^((?: {4})*)}{" " x (2*length($1)/4)}e' file

sed:

sed -e 's/^/~/' -e ': r' -e 's/^\( *\)~    /\1  ~/' -e 't r' -e 's/~//' file

您可能要使用indent


我得到了Nested quantifiers in regex; marked by <-- HERE in m/^( {4}* <-- HERE )/ at -e line 1.
eddygeek

1
@eddygeek哦,的确如此,还有其他一些错误。我用实际的perl代码替换了gobbledygook。
吉尔(Gilles)“所以,别再邪恶了”

5

不直接的方法工作:

sed -r 's/ {4}/  /g'

如果没有,请在失败的地方输入一些信息。


1
这不会限制到该行的开头。如果您将其锚定在此处,则它将无法用于多个匹配项。所以我们在下面的unix.stackexchange.com/a/375200/259620中。
geek-merlin

如果您有2个空格和4个空格的组合,这将不起作用,因为两个的两个缩进将被计为四个...
Matt Fletcher

@aexl:这不是OP的要求
Thor

@mattfletcher:问题是要用2代替4个空格,所以我看不到你的意思
雷神

4

如果仅要转换前导空格:

sed 'h;s/[^ ].*//;s/    /  /g;G;s/\n *//'

有评论:

sed '
  h; # save a copy of the pattern space (filled with the current line)
     # onto the hold space
  s/[^ ].*//; # remove everything starting with the first non-space
              # from the pattern space. That leaves the leading space
              # characters
  s/    /  /g; # substitute every sequence of 4 spaces with 2.
  G; # append a newline and the hold space (the saved original line) to
     # the pattern space.
  s/\n *//; # remove that newline and the indentation of the original
            # line that follows it'

还要看一下vim的'ts'设置和:retab命令


使用您的vim解决方案,有没有办法使用vim批量编辑几个文件?否则我猜我将不得不创建一个宏?
chrisjlee 2012年

请注意,'ts':retab不是解决问题的方法,而是相关的,可能有助于解决您的总体目标。您可以做vim -- *.c:set ts=...然后:argdo retab:argdo retab!。另请参见'sw'选项和vim自身的缩进功能。
斯特凡Chazelas

2
sed 's/^\( \+\)\1\1\1/\1\1/' file

它的工作原理是将前导空格划分为同一组的四个实例(因此它们都相等),然后仅用该组的两个实例替换它们。


如何改善现有解决方案?
Philippos

1
它保留奇数空格,仅影响前导空格,不需要全局标志,可以轻松地进行调整以处理替换两侧的任意数量的空格(或制表符),并且不使用更复杂的sed命令可能会让更多休闲用户不满意。与许多事情一样,这是否是一个改进是相当主观的,但是对于我自己来说:与其他列出的其他解决方案相比,在脚本中快速找到它显然要容易得多。

有趣。很高兴我确实问过。通常,反向引用被认为是邪恶的,而不是全局标志。但是,您可以使用更具移植性的脚本轻松地实现相同的目的(避免使用\+)。谢谢。
Philippos

1
sed 's/    \{2,4\}\( \{0,1\}[^ ].*\)*/  \1/g' <input

那只会挤压空间的前导序列。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.