Сценарий оболочки: вставьте несколько строк в файл ТОЛЬКО после того, как указанный шаблон появится в ПЕРВЫЙ раз. (Шаблон появляется несколько раз)

avatar
Diving
8 августа 2021 в 16:40
59
2
0

Я хочу вставить несколько строк в файл с помощью сценария оболочки. Рассмотрим мой исходный файл: original.txt:

.
aaa
bbb
ccc
aaa
bbb
ccc
aaa
bbb
ccc
.
.
.

и мой файл вставки: toinsert.txt

111
222
333

Теперь мне нужно вставить три строки из файла 'toinsert.txt' ТОЛЬКО после того, как строка 'ccc' появится в ПЕРВЫЙ раз в файле 'original.txt'. Примечание. Шаблон «ccc» появляется более одного раза в моем файле «original.txt». После вставки ТОЛЬКО после того, как шаблон появится в ПЕРВЫЙ раз, мой файл должен измениться следующим образом:

aaa
bbb
ccc
111
222
333
aaa
bbb
ccc
aaa
bbb
ccc
.
.
.

Я должен выполнить указанную выше вставку с помощью сценария оболочки. Кто-нибудь может мне помочь?

Примечание 2: я нашел аналогичный случай с частичным решением:

sed -i -e '/ccc/r toinsert.txt' original.txt

который фактически выполняет вставку несколько раз (каждый раз, когда появляется шаблон ccc).

Источник
Olaf
8 августа 2021 в 16:47
3

Не могли бы вы удалить теги PowerShell, если ваш вопрос не о PowerShell? Если это так, вы должны разработать немного более подробно. Заранее спасибо. ;-)

Santiago Squarzon
8 августа 2021 в 17:07
1

Как упомянул Олаф, вы ищете Powershell или решение оболочки?

Diving
8 августа 2021 в 17:09
0

Готово. Теги PowerShell удалены. Я ищу решение сценария Shell. Спасибо!

Ответы (2)

avatar
Shawn
8 августа 2021 в 18:04
2

Используйте ed, а не sed, для редактирования файлов:

printf "%s\n" "/ccc/r toinsert.txt" w | ed -s original.txt

Он вставляет содержимое другого файла после первой строки, содержащей ccc, но в отличие от вашей версии sed, только после первой.

avatar
potong
9 августа 2021 в 11:43
2

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

sed '0,/ccc/!b;/ccc/r insertFile' file

Используйте диапазон:

Если текущая строка находится в диапазоне после первого вхождения ccc, прекратить дальнейшую обработку и неявно вывести как обычно.

В противном случае, если текущая строка содержит ccc, вставьте строки из insertFile.

Н.Б. Здесь используется адрес 0, который позволяет регулярному выражению появляться в строке 1 и характерен для GNU sed.

или:

sed -e '/ccc/!b;r insertFile' -e ':a;n;ba' file

Использовать цикл:

Если строка не содержит ccc, дальнейшая обработка не выполняется и печатается как обычно.

В противном случае вставьте строки из insertFile, а затем, используя цикл, извлеките/напечатайте оставшиеся строки до конца файла.

Н.Б. Команда r настаивает на том, чтобы отделяться от других команд sed символом новой строки. Параметр -e имитирует этот эффект, поэтому команды sed делятся на два параметра -e.

или:

sed 'x;/./{x;b};x;/ccc/!b;h;r insertFile' file

Использовать флаг:

Если пространство для хранения не пусто (флаг уже установлен), дальнейшая обработка не выполняется и печать выполняется как обычно.

Иначе, если строка не содержит ccc, дальнейшая обработка не выполняется и печатается как обычно.

В противном случае скопируйте текущую строку в область хранения (установите флаг) и вставьте строки из insertFile.

Н.Б. Во всех случаях команда r вставляет строки из insertFile после печати текущей строки.