2

Например, если у меня была строка, которая начиналась в начале, и мне нужно было, чтобы она соответствовала предыдущей строке, как я могу сделать это наиболее эффективно.

      preceeding line
line I need to add spaces to

Так это выглядит так:

       predeeding line
       where it needs to start. 

Его ровно в 8 местах от того, где он должен начать. Как я могу сделать это с помощью vim, awk или sed или другого инструмента?

Другие требования / примечания:

Эти строки встречаются в моем файле несколько раз, и я хочу внести изменения только между строками 100-500.

3 ответа3

2

В VIM:

:100,500g/^[^ ]/normal 0ky^jP

Объяснение:

Команда "global" в vim будет применять команду ex к каждой строке, соответствующей определенному регулярному выражению. Это может быть ограничено определенным диапазоном линий, в данном случае 100-500. Регулярное выражение здесь

^[^ ]

Что означает любой символ, кроме пробела в начале строки. Команда ex

normal 0ky^jP

Что это делает:

0           "Move to the first character on this line
 k          "Move up one line
  y^        "Yank up to the first non-whitespace character
    j       "Move down one line
     P      "Paste what we just yanked

После запуска просто позвоните

:wq

Чтобы сохранить ваш файл и выйти. Вы также можете сделать это все из командной строки:

vim myfile.txt -c "100,500g/^[^ ]/normal 0ky^jP" -c "wq"

Другое альтернативное решение:

:%s/\v^(\s+).*\n\zs(\S)/\1\2
1

Давайте рассмотрим этот тестовый файл:

$ cat file1
      preceeding line
line I need to add spaces to
    preceeding line
  preceeding line
line I need to add spaces to

Следующие отступы строк без отступа соответствуют отступу предыдущей строки:

$ awk '{if (/^[^ \t]/) $0=x $0; else {x=$0; sub(/[^ \t].*/, "", x);}} 1' file1
      preceeding line
      line I need to add spaces to
    preceeding line
  preceeding line
  line I need to add spaces to

Как это устроено

  • if (/^[^ \t]/) $0=x $0; else {x=$0; sub(/[^ \t].*/, "", x);}

    Если строка начинается с пустой строки или табуляции, добавьте отступ x в начало строки.

    В противном случае сохраните отступ из текущей строки в переменной x .

  • 1

    Это загадочное сокращение awk для print-the-line.

Многострочная версия

Для тех, кто предпочитает свой код в несколько строк:

awk '
    {
        if (/^[^ \t]/) 
           $0=x $0
        else { 
            x=$0
            sub(/[^ \t].*/, "", x)
        }
    } 

    1' file1

Ограничение изменений в строках от 100 до 500

awk 'NR>=100 && NR<=500 {if (/^[^ \t]/) $0=x $0; else {x=$0; sub(/[^ \t].*/, "", x);}} 1' file1

Изменение файла на месте

Использование GNU awk:

awk -i inplace 'NR>=100 && NR<=500 {if (/^[^ \t]/) $0=x $0; else {x=$0; sub(/[^ \t].*/, "", x);}} 1' file1

Использование BSD/OSX awk:

 awk 'NR>=100 && NR<=500 {if (/^[^ \t]/) $0=x $0; else {x=$0; sub(/[^ \t].*/, "", x);}} 1' file1 >tmp && mv tmp file1
0

Домашнее задание? ; ->

sed -e '100,500s/^[ ]*/        /' -i file

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