Xml sed不能从bash内部工作

Xml sed不能从bash内部工作,xml,bash,sed,Xml,Bash,Sed,我正在尝试使用sed替换外部文件中的${SRC}和${MSG}。它们都是在下面的bash脚本中可用的变量 #!/bin/bash SRC=$1 DST=$2 MSG=$3 CONN=$4 GROUP=$5 echo "$SRC","$DST","$MSG","$CONN","$GROUP" >> /home/maaz/smpp/smppin/incoming.log /usr/bin/sed -i -e "s/\${SRC}/$SRC/" -e "s/\${MSG}/$MSG

我正在尝试使用sed替换外部文件中的${SRC}和${MSG}。它们都是在下面的bash脚本中可用的变量

#!/bin/bash

SRC=$1
DST=$2
MSG=$3
CONN=$4
GROUP=$5


echo "$SRC","$DST","$MSG","$CONN","$GROUP" >> /home/maaz/smpp/smppin/incoming.log

/usr/bin/sed -i -e "s/\${SRC}/$SRC/" -e "s/\${MSG}/$MSG/" request.xml >> request.xml
文件request.xml如下所示:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tem="http://tempuri.org/">
   <soapenv:Header/>
   <soapenv:Body>
      <tem:SendSMS>
        <!--Optional:-->
         <tem:Number>${SRC}</tem:Number>
         <!--Optional:-->
         <tem:AccountID>${MSG}</tem:AccountID>
      </tem:SendSMS>
   </soapenv:Body>
</soapenv:Envelope>

${SRC}
${MSG}
我需要用bash中相应的值替换文本${SRC}和${MSG}。此时,同一个sed表达式正在替换文本(如果从bash外部运行),但在调用脚本时文件中没有任何更改

任何帮助都将不胜感激。

下面的脚本可以:

dst=$2 # Uppercase variables are usually reserved for the system
msg=$3 # So use lowercase variables for your scripts like 'dst','msg' and so
.
.
.
sed -E -i 's/\$\{SRC\}/'"$src"'/g;s/\$\{MSG\}/'"$msg"'/g' request.xml
注释

  • 在位编辑选项
    -i
    使更改在文件中生效
  • 决不能同时读取和写入文件
  • 双重引用变量(例如
    SRC=“$1”
    )没有害处。这将防止在变量中拆分单词
  • 带有sed的
    -E
    选项更便于携带,目前大多数sed版本都认可它
  • 编辑
    如果未启用扩展正则表达式,则可以编写如下sed语句:

    sed -i 's/\${SRC}/'"$src"'/g;s/\${MSG}/'"$msg"'/g' request.xml
    
    下面的脚本将执行以下操作:

    dst=$2 # Uppercase variables are usually reserved for the system
    msg=$3 # So use lowercase variables for your scripts like 'dst','msg' and so
    .
    .
    .
    sed -E -i 's/\$\{SRC\}/'"$src"'/g;s/\$\{MSG\}/'"$msg"'/g' request.xml
    
    注释

  • 在位编辑选项
    -i
    使更改在文件中生效
  • 决不能同时读取和写入文件
  • 双重引用变量(例如
    SRC=“$1”
    )没有害处。这将防止在变量中拆分单词
  • 带有sed的
    -E
    选项更便于携带,目前大多数sed版本都认可它
  • 编辑
    如果未启用扩展正则表达式,则可以编写如下sed语句:

    sed -i 's/\${SRC}/'"$src"'/g;s/\${MSG}/'"$msg"'/g' request.xml
    

    检查系统上的sed路径是否为
    /usr/bin/sed

    这是我的
    /bin/sed

    检查您的系统上是否有sed路径
    /usr/bin/sed

    这是我的
    /bin/sed

    忽略您的输入文件是XML,
    envsubt
    是用同名环境变量中的值替换
    ${foo}
    表单占位符的正确工具

    src=$1; dst=$2; msg=$3; conn=$4; group=$5
    tempfile=$(mktemp -t request.xml.XXXXXX)
    
    # to edit request.xml in-place:
    SRC=$src DST=$dst MSG=$msg CONN=$conn GROUP=$group envsubst \
      <request.xml >"$tempfile" && mv "$tempfile" request.xml
    
    src=$1;dst=2美元;味精=$3;康涅狄格州=4美元;团体=5美元
    tempfile=$(mktemp-t request.xml.XXXXXX)
    #要就地编辑request.xml,请执行以下操作:
    SRC=$SRC DST=$DST MSG=$MSG CONN=$CONN GROUP=$GROUP ENVSUT\
    “$tempfile”和&mv“$tempfile”request.xml
    

    这就是说,如果我们不忽略这一点,并选择使用支持XML的工具,我们会想出一个完全不同的解决方案:

    #!/bin/bash
    SRC=hello
    MSG=world
    tempfile=$(mktemp request.xml.XXXXXX)
    xmlstarlet ed -u '//*[.="${SRC}"]' -v "$SRC" \
                  -u '//*[.="${MSG}"]' -v "$MSG" \
      <request.xml >"$tempfile" && mv "$tempfile" request.xml
    
    #/bin/bash
    你好
    MSG=世界
    tempfile=$(mktemp request.xml.XXXXXX)
    xmlstarlet ed-u'/*[.=“${SRC}”]'-v“$SRC”\
    -u'/*[.=“${MSG}”]'-v“$MSG”\
    “$tempfile”和&mv“$tempfile”request.xml
    
    …根据您的输入文件,生成:

    <?xml version="1.0"?>
    <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tem="http://tempuri.org/">
      <soapenv:Header/>
      <soapenv:Body>
        <tem:SendSMS>
          <!--Optional:-->
          <tem:Number>hello</tem:Number>
          <!--Optional:-->
          <tem:AccountID>world</tem:AccountID>
        </tem:SendSMS>
      </soapenv:Body>
    </soapenv:Envelope>
    
    
    你好
    世界
    

    …并保证以有效的XML格式输出,即使要替换的字符串需要转义或修改以使其在XML中有效。

    忽略输入文件是XML,
    envsubst
    是替换表单的占位符的正确工具。
    ${foo}
    使用同名环境变量中的值

    src=$1; dst=$2; msg=$3; conn=$4; group=$5
    tempfile=$(mktemp -t request.xml.XXXXXX)
    
    # to edit request.xml in-place:
    SRC=$src DST=$dst MSG=$msg CONN=$conn GROUP=$group envsubst \
      <request.xml >"$tempfile" && mv "$tempfile" request.xml
    
    src=$1;dst=2美元;味精=$3;康涅狄格州=4美元;团体=5美元
    tempfile=$(mktemp-t request.xml.XXXXXX)
    #要就地编辑request.xml,请执行以下操作:
    SRC=$SRC DST=$DST MSG=$MSG CONN=$CONN GROUP=$GROUP ENVSUT\
    “$tempfile”和&mv“$tempfile”request.xml
    

    这就是说,如果我们不忽略这一点,并选择使用支持XML的工具,我们会想出一个完全不同的解决方案:

    #!/bin/bash
    SRC=hello
    MSG=world
    tempfile=$(mktemp request.xml.XXXXXX)
    xmlstarlet ed -u '//*[.="${SRC}"]' -v "$SRC" \
                  -u '//*[.="${MSG}"]' -v "$MSG" \
      <request.xml >"$tempfile" && mv "$tempfile" request.xml
    
    #/bin/bash
    你好
    MSG=世界
    tempfile=$(mktemp request.xml.XXXXXX)
    xmlstarlet ed-u'/*[.=“${SRC}”]'-v“$SRC”\
    -u'/*[.=“${MSG}”]'-v“$MSG”\
    “$tempfile”和&mv“$tempfile”request.xml
    
    …根据您的输入文件,生成:

    <?xml version="1.0"?>
    <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tem="http://tempuri.org/">
      <soapenv:Header/>
      <soapenv:Body>
        <tem:SendSMS>
          <!--Optional:-->
          <tem:Number>hello</tem:Number>
          <!--Optional:-->
          <tem:AccountID>world</tem:AccountID>
        </tem:SendSMS>
      </soapenv:Body>
    </soapenv:Envelope>
    
    
    你好
    世界
    

    …并保证以有效的XML格式输出,即使要替换的字符串需要转义或修改以使其在XML中有效。

    如果将
    -i
    sed
    一起使用,它会自动在位编辑文件。从一个同样是输入的文件重定向输出通常会留下一个空文件。只需从末尾删除request.xml。@AndrasDeak,它不是
    >
    ,所以OP可能不会留下空文件。另外,由于此命令不生成任何
    stdout
    (因为
    -i
    ),这可能会起作用,尽管这是错误的方式……@AndrasDeak,
    -i
    不是
    sed
    的POSIX标准的一部分,并且不是所有操作系统和实现都提供它。此外,并非所有的实现都是兼容的--
    sed-i-e“expression”filename
    在GNU-sed上工作,但不是MacOS-sed,它要求在
    -i
    后面加一个文件扩展名以附加到备份中(在GNU版本中是可选的)。顺便说一句,使用sed编辑xml非常有用,非常不赞成——当您的输入文件或要替换的内容以微小的方式更改时,您很可能会得到一个损坏的输出文件。知识库中不乏关于如何正确操作的问题和答案,因此我不会详细阐述这一点。您的脚本非常脆弱-您需要在最初的示例中引用
    $1
    $5
    ,例如,当扩展替换时,您需要将用作sed的
    s
    命令分隔符的
    /
    转义(例如,
    sed-es/'${SRC}'/“${SRC/\/\/\/\/\/}”/
    )。当然,还可以删除
    -i
    标志。如果将
    -i
    sed
    一起使用,它会自动在位编辑文件。从同时也是输入wi的文件重定向输出