将混合空格/制表符的文本文件转换为仅制表符(在可能的情况下)。

7
我有一些源代码文件,其中混合了制表符/空格,我想将其转换为一个文件,其中所有缩进空格都被自动替换为给定制表符长度的制表符(例如 tab = 2 spaces)。
有没有简单的解决方案(使用常见的Unix工具、MacOSX、bash或zsh)?一些sed脚本或Python命令之类的东西?
谢谢, 阿尔伯特

请问谁在这里投了关闭票?为什么?而且为什么没有留下评论? - Albert
很抱歉要投票关闭,一开始我认为这应该属于superuser.com,但后来发现这需要编程才能完成。 - Philipp
7个回答

5

1

根据源语言的不同,您可以尝试使用GNU indent。它可以执行许多与源代码缩进相关的操作,但可能比您需要的更复杂。

例如,如果我将以下程序提供给indent -di0 <inputfile>

#include <stdio.h>

int main(int argc, char **argv)
{
  int i;
    int j;
  for (i = 0; i < 10; i++)
    {
        for (j = 0; j < 10; j++)
    {
        printf("x");
    }
  }
}

它将用以下内容替换:

#include <stdio.h>

int 
main(int argc, char **argv)
{
    int i;
    int j;
    for (i = 0; i < 10; i++) {
        for (j = 0; j < 10; j++) {
            printf("x");
        }
    }
}

或者,如果你需要非常简单的东西,可以使用expand/unexpand命令。


“缩进”不起作用(这是Python - 虽然我也在寻找适用于其他情况的解决方案)。 “展开”/“收缩”太简单了(基本上像这里给出的大多数其他解决方案一样)。 :) - Albert
也许 http://svn.python.org/projects/python/trunk/Tools/scripts/reindent.py 上的 reindent.py 脚本可以为您提供所需的基础? - mjschultz
1
嘿,那个reindent.py看起来大部分都是我想要的。:) 好吧,没有深入研究它,不确定它是否只适用于Python(这会立即帮助我,但不是我正在寻找的通用解决方案)。现在我自己编码了... - Albert

0
你可以使用正则表达式将N个空格替换为制表符。例如在Python中: ```python import re re.sub(r' {N}', '\t', your_string) ```
import re
re.sub('[ ]{4}', '\t', text)

这并不容易。例如,这将不仅替换用于缩进的空格,而且还会替换到其他所有位置(而它不应该这样做)。 - Albert

0
sed -r 's/ {2}/\t/g' file

这并不容易。例如,这将不仅替换用于缩进的空格,而且还会替换到其他所有位置(而它不应该这样做)。 - Albert

0

以下是Python的一种可能解决方案:

import re
import fileinput

pat = re.compile("^(  )+")

for line in fileinput.input(inplace=True):
    print pat.sub(lambda m: "\t" * (m.end() // 2), line, 1),

好的,这比其他解决方案更好,但如果已经混合使用了空格/制表符,则无法正常工作。例如 "\t \t" 应该变成 "\t" * 3 - Albert
如果您将正则表达式替换为“^( |\t)+”,它是否有效?我想我并不完全理解要求。编辑: 新正则表达式中是两个空格,行内代码标记不幸地折叠了空格。 - Philipp

0

这将把前导空格(即使与制表符交替)转换为制表符。通过设置变量来指定要转换的空格数量。杂散的空格将被折叠成空白。任何字符之后出现的空格和制表符都不会被触及。

tstop=2
sed "s/^\([[:blank:]]*\)\(.*\)/\1\n\2/;h;s/[^[\n]*//;x;s/\n.*//;s/ \{$tstop\}/X/g;s/ //g;G;s/\n//g" inputfile

例子:

[space][space][tab][tab][space][space][space][tab][space]TEXT[space][space][space]

将被转换为

[tab][tab][tab][tab][tab]TEXT[space][space][space]

如果这并不完全符合您的要求,我们可以进行调整。


完全看不懂,但看起来就是我搜索的内容。 :) 另外,输出的应该是 ...[制表符][空格]文本,至少那是我想要的。 - Albert
我正在删除所有杂散的空格。对于tstop=2,你希望[tab][space][tab]...TEXT看起来像什么?那么[tab][space][space]TEXT呢? - Dennis Williamson
[t][s][t]文本 应该变成 [t][t]文本。 [t][s][s]文本 应该变成 [t][t]文本。 [t][s]文本应该保持不变。 - Albert

0

两件事情,

  1. sed -i 是你的好朋友 - sed -i XXX.txt 's/^[ ]\{2\}/\t/g'
  2. 你不能用正则表达式将制表符替换成空格长度的倍数。

鉴于我的 AWK 技能不强(而且我不知道它是否能做到 #2 无法做到的),我将编写一个 PHP 脚本来计算空格并用制表符替换它们。


好的,那至少只会替换开头的空格。虽然它不会多次替换。我可能会编写一个Python脚本来为我完成这个任务。 - Albert

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接