Как заменить имена переменных в xml-файле?

#bash #shell #unix #ant

#bash #оболочка #unix #ant

Вопрос:

Инструмент сборки Java ant предоставляет фильтр для замены переменных по их значениям

Пример: файл со свойствами:

 db.user.name=user
db.driver=com.informix.jdbc.IfxDriver
  

XML-файл с общими настройками (обратите внимание на @variables@ )

 <driver-class>@db.driver@</driver-class>
<user-name>@db.user.name@</user-name>
  

становится после обработки с помощью фильтра

 <driver-class>com.informix.jdbc.IfxDriver</driver-class>
<user-name>user</user-name>
  

Как можно достичь такой функциональности с помощью bash и обычных инструментов unix?

Ответ №1:

Это другая реализация, использующая только bash. Если вы можете использовать версию python для своих нужд, я бы посоветовал это. Это будет проще поддерживать. В противном случае вы могли бы попробовать использовать этот скрипт bash:

 #!/bin/bash

config="$1"
xml="$2"

tmp=$(mktemp)

cat "$config" | while read line; do

    key=`echo $line | sed -n 's/^([^=] )=(.*)$/1/p'`
    value=`echo $line | sed -n 's/^([^=] )=(.*)$/2/p'`

    echo " sed 's/@$key@/$value/g' | " >> $tmp
done
replacement_cmd=`cat $tmp`
eval "cat "$xml" | $replacement_cmd cat"

rm -f $tmp
  

Ответ №2:

 sed -e 's/@db.driver@/com.informix.jdbc.IfxDriver/g' -e 's/@db.user.name@/user/g' > outfile.xml
  

Комментарии:

1. Спасибо за ваш ответ ( 1), речь идет не только о замене статического текста, файл свойств должен быть входным файлом, поскольку он содержит довольно много определений. Но, похоже, я мог бы сгенерировать sed-скрипт из этого файла.

2. Ах, я не понял этого нюанса. Вы также могли бы использовать sed для преобразования каждой строки файла свойств в команду sed, которую я предоставил. Я обновлю ответ выше позже, чтобы отразить это.

Ответ №3:

Вы можете сделать это с помощью очень короткого скрипта практически на любом языке — вот пример на Python:

 #!/usr/bin/env python

import sys, re

if len(sys.argv) != 3:
    print "Usage: %s <mapping-file> <input-file>" % (sys.argv[0],)
    sys.exit(1)

mapping_file, input_file = sys.argv[1:]

mapping = {}

with open(mapping_file) as fp:
    for line in fp:
        m = re.search(r'^(.*?)=(.*)$',line)
        if m:
            mapping[m.group(1).strip()] = m.group(2).strip()

def replace_from_mapping(m):
    return mapping.get(m.group(1), m.group(0))

with open(input_file) as fp:
    text = fp.read()
    text = re.sub(r'@(.*?)@', replace_from_mapping, text)
    sys.stdout.write(text)