Вопрос

У меня есть файл с именем «insert.txt». Это может выглядеть так (или уродье):

ASDFG?|??|?\/\HJKL<MNBVCXZQWERTYUIOP
zxvbnmlkjhgfdsaqwertyuiop
123"'`~4567890987654321!@#$%^&*()
@#$%^&*()+_}{":?>

И я хочу заменить блок текста в целевой файл (Target.txt), который разграничен «StartStackverflow» на «StortStackFlow». (Я немного упрощаю вопрос, но это то же самое).

Сценарий Bash, который я использую для этого:

TARGETFILE=target.txt
SOURCEFILE=insert.txt
SOURCETXT="$(<$SOURCEFILE)"
DELIMTXT=$(printf "%q" "$SOURCETXT")

sed -i -e "/STARTSTACKOVERFLOW/,/STOPSTACKOVERFLOW/cSTARTSTACKOVERFLOW\n\n${DELIMTXT}\n\nSTOPSTACKOVERFLOW\n" $TARGETFILE

Проблема в том, что то, что вставлено в «target.txt» на самом деле ANSI-C представляет собой:

$'ASDFG?|??|?\/\HJKL<MNBVCXZQWERTYUIOP
zxvbnmlkjhgfdsaqwertyuiop
123"'`~4567890987654321!@#$%^&*()
@#$%^&*()+_}{":?>'

Обратите внимание на добавление $ ''.

Причина в том, что PrintF «% Q» производит этот стиль цитирования. Я хотел бы избежать этого - хотя это нужно, потому что я должен избежать всю плохое в этом файле.

Есть ли лучший способ сделать вышеупомянутое использование Bash и Sed?

Это было полезно?

Решение

POSIX SED имеет команду «R» для чтения из файла. Так:

sed -i -e '/STARTSTACKOVERFLOW/,/STOPSTACKOVERFLOW/r large.txt' target.txt

Единственная проблема заключается в том, прочитан ли файл один раз или один раз в соответствии между строками начала и остановки. Я подозреваю, что это читается один раз на линию ... и разработать, как бросить дополнительные линии прочь сложнее ... Но может быть:

sed -i -e '/STOPSTACKOVERFLOW/r large.txt' \
       -e '/STARTSTACKOVERFLOW/,/STOPSTACKOVERFLOW/d' target.txt

Простое демонстрация

Эта версия удаляет начальные и конечные маркеры.

$ cat data
sdasas
adsasdas
start
more
more
end
sdasda
sdasdad
$ cat replace
replace1
replace2
replace3
$ sed -e '/^end$/r replace' -e '/start/,/end/d' data
sdasas
adsasdas
replace1
replace2
replace3
sdasda
sdasdad

Сохранение стартовых и конечных маркеров

$ cat sedfile
/^end$/{
a\
start
r replace
a\
end
}
/^start$/,/^end$/d
$ sed -f sedfile data
sdasas
adsasdas
start
replace1
replace2
replace3
end
sdasda
sdasdad
$ 

Это Fiddlier - я бы не пытался сделать это без использования файла для скрипта, но вы можете сделать, если вы хотите. Это не одноклассник, хотя.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top