Я хочу заменить начальные вкладки и пробелы на что-то вроде <TAB> и <SPACE> соответственно. Но я не мог понять, как это сделать за один проход sed потому что вкладки и пробелы в исходном файле могут быть смешаны, поэтому просто сделать одну замену, а затем другую не получится.

Пример ввода (вкладки показаны как ^):

^^line with tabs
  line with spaces
^ ^intermixed

Желаемый результат:

<TAB><TAB>line with tabs
<SPACE><SPACE>line with spaces
<TAB><SPACE><TAB>intermixed

2 ответа2

2

Я знаю, что вы сказали, что хотите использовать sed , который часто является замечательным инструментом. Но там, где есть выбор и циклы, я обнаружил, что awk затмевает это.

#!/usr/bin/gawk -f
{ while (/^\s/) {
    if (sub(/^ /,"")) printf "<space>";
    if (sub(/^\t/,"")) printf "<tab>";
    }
  print;
}

Если мы создадим файл input.txt содержащий пример ввода, и назовем сценарий replace , он будет выполнен следующим образом, что даст желаемый результат.

replace input.txt

ОБНОВЛЕНИЕ: Ой. В этом коде есть бесконечный цикл. Последовательность \s совпадает с [ \t\n\r\f\v] , поэтому, если есть случайная подача формы, она будет вращаться вечно. Но [:blank:] соответствует только пробелу и табуляции, поэтому вторая строка должна быть такой.

{ while (/^[[:blank:]]/) {
0

Одно из решений с помощью sed - это разделение строки на отдельные табуляции и пробелы в начале от остальной части строки, чтобы избежать замены каких-либо табуляций и пробелов в тексте.

echo -e '\t\tline with\ttabs
  line with spaces
\t \tintermixed' | sed -r '

    # On the lines that start with tab or space.
    /^[\t ]/ {

        # Put the whole line in the hold space.
        h

        # Delete all tabs and spaces at the start of line.
        s/^[\t ]+//

        # Exchange pattern and hold spaces.
        # This saves the text part to the hold space and
        # bring back the original line to the pattern space.
        x

        # Now let in pattern space only tabs and spaces
        # at the start of line (the rest is on hold space).
        s/^([\t ]+).*/\1/

        # At least make the substitutions.
        s/\t/<TAB>/g
        s/ /<SPACE>/g

        # Add a \n (new line) at the end of pattern space,
        # then get the content of hold space and append it
        # to pattern space.   
        G

        # Delete the extra \n added above.
        s/\n//
    }'
<TAB><TAB>line with     tabs
<SPACE><SPACE>line with spaces
<TAB><SPACE><TAB>intermixed

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .