Вы можете делать то, что вы пытаетесь (до некоторой степени) с sed
и while read -r
петли. Например, вы можете заполнить временный файл с содержимым файла XML из строки 1 в <targettag>
с
sed -n "1, /^${ttag}$/p" "$xfn" > "$ofn" ## fill output to ttag
(где xfn
ваше имя файла XML и ofn
это имя файла, на выходе)
Вы можете прочитать все значения из текстового файла и предварять componentName="
и добавить "
с:
while read -r line; do ## read each line in ifn and concatenate
printf "%s%s\"\n" "$cmptag" "$line" >> "$ofn"
done <"$ifn"
(где ifn
ваш входной файл на я)
И, наконец, вы можете написать закрывающий тег конец файла XML в свой выходной файл с:
sed -n "/^${ttag/</<[\/]}$/, \${p}" "$xfn" >> "$ofn"
(с использованием расширения параметров с заменой подстроки добавить закрытие '/'
к начало <targettag>
.
Собираем в целом, вы могли бы сделать что-то вроде:
#!/bin/bash
ifn="f1"
xfn="f2.xml"
ofn="f3.xml"
ttag="${1:-<targettag>}" ## set target tag
cmptag="componentName=\"" ## set string to prepend
sed -n "1, /^${ttag}$/p" "$xfn" > "$ofn" ## fill output to ttag
while read -r line; do ## read each line in ifn and concatenate
printf "%s%s\"\n" "$cmptag" "$line" >> "$ofn"
done <"$ifn"
## fill output from closing tag to end
sed -n "/^${ttag/</<[\/]}$/, \${p}" "$xfn" >> "$ofn"
входных файлов
$ cat f1
ABC
EFG
XYZ
$ cat f2.xml
<someschema>
<targettag>
</targettag>
</someschema>
Пример использования/вывода
$ fillxml.sh
$ cat f3.xml
<someschema>
<targettag>
componentName="ABC"
componentName="EFG"
componentName="XYZ"
</targettag>
</someschema>
(вы можете настроить инден тации в соответствии с вашими потребностями)
Добавления После изменений на вопрос
изменения, необходимого для обработки письменной формы от start
до конца после добавления componentName="..."
тегов просты. Однако общность слова start
иллюстрирует, почему ответ Чарльза рекомендует использовать инструмент XML, а не простой скрипт. Зачем?Если слово «start» происходит где-либо еще в вашем файле .xml
до вашего предполагаемого start
, сценарий завершится неудачей, записав для первого вхождения start
в конец.
Тем не менее, если это простой двухпозиционный преобразования и start
не происходит иначе, то изменения в сценарий, чтобы достигнуть нужного вывода легко:
#!/bin/bash
ifn="f1"
xfn="another.xml"
ofn="f3.xml"
ttag="${1:-<compile>}" ## set target tag
cmptag="componentName=\"" ## set string to prepend
sed -n "1, /^${ttag}$/p" "$xfn" > "$ofn" ## fill output to ttag
## read each line in ifn and concatenate
while read -r line || [ -n "$line" ]; do
printf "%s%s\"\n" "$cmptag" "$line" >> "$ofn"
done <"$ifn"
## fill output from 'start' to end
sed -n "/^start/, \${p}" "$xfn" >> "$ofn"
Входные файлы
$ cat f1
ABC
EFG
XYZ
$ cat another.xml
<project>
<compile>
start
shell
script
xyz
</compile>
</project>
Пример использования/выход
$ cat f3.xml
<project>
<compile>
componentName="ABC"
componentName="EFG"
componentName="XYZ"
start
shell
script
xyz
</compile>
</project>
Посмотрите и сообщите мне, если у вас есть вопросы.
Есть * тааак * много случаев, когда это будет вести себя плохо. Что делать, если '' также отображается внутри раздела CDATA или комментария? Что делать, если оно находится в псевдониме? Что делать, если одна из заменяемых строк должна быть экранирована, чтобы быть допустимым XML? Что делать, если кто-то добавляет атрибут к этому тегу, делая его ' '? –
Согласовано. Я не сторонник разбора xml с bash по всем причинам, которые вы цитируете (таким образом, квалификация «в некоторой степени»). Для этого ограниченного случая, конечно, как обобщение, нет. –
thnx @ DavidC.Rankin для решения, но с этим решением мне нужно также выполнить мое требование. После того как вы создали окончательный xml со всей строкой componentName и когда вы собираетесь закрыть цель. Я не хочу закрывать тег, хотя я хочу скопировать еще текст перед закрытием цели и после имени компонента. Можете ли вы, пожалуйста, помочь команде скопировать текст из определенного содержимого, написанного в f2.xml, позволяет сказать, что слово «start» написано в f2.xml, и я хочу скопировать из этого слова в EOF в f3.xml, когда я создал f3.xml до имени компонента. – user6376225