Конвертировать TXT-файл со смешанными пробелами / табуляциями только во вкладки (где это возможно)

У меня есть некоторый файл исходного кода, который содержит смешанные табуляции / пробелы, и я хочу преобразовать его в файл, в котором он автоматически заменит все отступы на табуляцию для заданной длины табуляции (например, табуляция = 2 пробела).

Любое простое решение (с обычными инструментами Unix, MacOSX, bash или zsh)? Какой-нибудь сценарий sed или команда Python или около того?

Спасибо Альберт

7 ответов

Решение

Хорошо, ни одно из приведенных решений не удовлетворило меня, поэтому я сам его кодировал.:)

Посмотреть здесь:

В зависимости от исходного языка вы можете попробовать отступ для GNU. Он может выполнять большое количество операций, связанных с отступом исходного кода, хотя он может быть более сложным, чем вам нужно.

Например, если я дам следующую программу 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 команды.

Две вещи,

  1. sed -i твой друг - sed -i XXX.txt 's/^[ ]\{2\}/\t/g'
  2. Вы не можете сделать регулярное выражение для умножения замены табуляции на длину пробела.

Учитывая, что мой AWK-фу не силен (и я не знаю, может ли он делать то, что не может #2), я напишу скрипт PHP, чтобы вычислить пробелы и заменить их на вкладки.

Вот возможное решение в 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),
sed -r 's/ {2}/\t/g' file

Это преобразует начальные пробелы (даже с вкладками) в вкладки. Укажите количество пробелов для преобразования, установив переменную. Бродячие места будут разрушены ни к чему. Пробелы и табуляции, которые появляются после любого символа, кроме пробела или табуляции, не будут затронуты.

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]

Если это не совсем то, что вы ищете, можно внести коррективы.

Вы можете использовать регулярное выражение для замены N пробелов символом табуляции. Например в Python:

import re
re.sub('[ ]{4}', '\t', text)
Другие вопросы по тегам