Использование ANSI-C цитируют в САГ
Вопрос
У меня есть файл с именем «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 - я бы не пытался сделать это без использования файла для скрипта, но вы можете сделать, если вы хотите. Это не одноклассник, хотя.