Команда оболочки Как вырезать несколько строк строки и переместить их в другую часть в одном файле - PullRequest
0 голосов
/ 13 марта 2020

У меня есть некоторый текст в файле someText.txt

{
  someOtherTexts
  debug {
     minifyEnabled true
     shrinkResources false
     {
       other
     }
  }

  release {
     print()
  }
}

Как мне скопировать содержимое в закрытии отладки и переместить его в закрытие релиза, которое будет показано ниже.

{
  someOtherTexts
  debug {
     minifyEnabled true
     shrinkResources false
     {
       other
     }
  }

  release {
     minifyEnabled true
     shrinkResources false
     {
       other
     }
     print()
  }
}

Я пробовал с

#search the next two lines after match
qaConfig=$(awk '/qa {/{x=NR+2;next}(NR<=x){print}' ./someText.txt)

#append after match
sed -i '' "/release {/a\\
${qaConfig}" ./someText.txt

Но выдает ошибку

sed: 3: "/release {/a\

         ...": invalid command code T

Любые подходы приветствуются.

Обновлено: в режиме реального Случай, у меня фактически есть внутренняя скобка в моем файле, поэтому я добавил ее и в мой пример. Вот почему мне пришлось go с фиксированным числом после совпадения.

обновлено: Спасибо за ваши решения, теперь все становится немного сложнее. Я должен добавить скобку вокруг всего текста. Есть ли способ справиться с этим тоже? спасибо

Ответы [ 3 ]

1 голос
/ 13 марта 2020

Это awk может работать:

awk '/^}/{p=0} p{s = s ORS $0} /^debug[ \t]*{/{p=1}
/^release[ \t]*{/{$0 = $0 s} 1' file

someOtherTexts
debug {
   minifyEnabled true
   shrinkResources false
   {
     other
   }
}

release {
   minifyEnabled true
   shrinkResources false
   {
     other
   }
   print()
}

Для сохранения вывода в одном файле используйте:

awk '/^}/{p=0} p{s = s ORS $0} /^debug[ \t]*{/{p=1}
/^release[ \t]*{/{$0 = $0 s} 1' file > file.tmp && mv file.tmp file
1 голос
/ 13 марта 2020

Вы можете установить флаг при обнаружении debug { и продолжать добавлять строки в буфер, если флаг установлен, до тех пор, пока флаг не будет сброшен при обнаружении }, и выводить буфер при обнаружении release {:

awk '/release {/{$0=$0s}1;/}/{--d}i&&d>=i{s=s ORS$0}d<i{i=0}/{/{++d}/debug {/{i=d}'

awk не поддерживает запись вывода обратно в тот же файл, поэтому вам придется сначала записать его во временный файл перед тем, как перезаписать исходный файл:

awk '...' input.txt > temp.txt && mv temp.txt input.txt

РЕДАКТИРОВАТЬ: Как отметил @anubhava, можно использовать обратную запись в тот же файл, если вы используете gawk, с опцией -i inplace.

РЕДАКТИРОВАТЬ 2: Также заимствование кода @ anubhava для добавления строк в строковый буфер, а не в массив.

0 голосов
/ 14 марта 2020

Это может работать для вас (GNU sed):

sed '/^  debug {/{h;:a;n;/^  }/b;H;ba};/^  release {/{p;g;D}' file

Если текущая строка начинается debug собирать строки до строки перед закрытием } для этого сегмента кода.

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

Это приводит к добавлению собранных строк (меньше первый) после начала строки release.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...