Bash прочитать строку и заменить значение предыдущей строкой - PullRequest
0 голосов
/ 18 января 2019

У меня есть приведенный ниже XML-файл, и я хочу заменить значение на значение Product ID.

Я использую приведенный ниже код, но он заменяет один и тот же продукт в обеих строках.

Я также предоставил образец исходного и целевого содержимого ниже.

 while read line
 do
 count=`echo $line | grep "Product ID" | wc -l`
 if [ $count -eq "1" ]
  then
 product=`echo "$line" | grep "Product ID"|awk -F "=" '{print $2}' | awk 
 '{print $1}'`

 name=`grep "$line" -B 1 test.xml | tail -1|sed 's/\///g;s/<Name>//g' | 
  awk '{print $1}'`

 echo $line | sed "s/$name/$product/g" >> data.xml
 else
 echo "$line" >> data.xml
 fi

 done < test.xml

Ниже приведен формат источника:

 <Products>
<Product ID="ABC1234" UserID="XYX" SUperUserID="ROOT" >
  <Name>1234</Name>  
  <Values>
    <Value AttributeID="A">1</Value>
    <Value AttributeID="B">00</Value>
     </Values>
</Product>
 <Product ID="XYZ1234" UserID="XYX" SUperUserID="ROOT" >
   <Name>1234</Name>
  <Value AttributeID="A">4</Value>
    <Value AttributeID="B">10</Value>
     </Values>
 </Product>

Ниже будет выходной формат:

<Products>
<Product ID="ABC1234" UserID="XYX" SUperUserID="ROOT" >
  <Name>ABC1234</Name>  
  <Values>
    <Value AttributeID="A">1</Value>
    <Value AttributeID="B">00</Value>
     </Values>
</Product>
 <Product ID="XYZ1234" UserID="XYX" SUperUserID="ROOT" >
   <Name>XYZ1234</Name>
  <Value AttributeID="A">4</Value>
    <Value AttributeID="B">10</Value>
     </Values>
 </Product>

Пожалуйста, предложите любой другой подход.

Ответы [ 2 ]

0 голосов
/ 18 января 2019

Использование Perl однострочного

 perl -0777 -pe ' s/(<Product ID=\"(\S+)\".+?<Name>)(.+?)</$1$2</msg '

с заданными входами

$ cat navku.xml
 <Products>
<Product ID="ABC1234" UserID="XYX" SUperUserID="ROOT" >
  <Name>1234</Name>
  <Values>
    <Value AttributeID="A">1</Value>
    <Value AttributeID="B">00</Value>
     </Values>
</Product>
 <Product ID="XYZ1234" UserID="XYX" SUperUserID="ROOT" >
   <Name>1234</Name>
  <Value AttributeID="A">4</Value>
    <Value AttributeID="B">10</Value>
     </Values>
 </Product>
$ perl -0777 -pe ' s/(<Product ID=\"(\S+)\".+?<Name>)(.+?)</$1$2</msg ' navku.xml
 <Products>
<Product ID="ABC1234" UserID="XYX" SUperUserID="ROOT" >
  <Name>ABC1234</Name>
  <Values>
    <Value AttributeID="A">1</Value>
    <Value AttributeID="B">00</Value>
     </Values>
</Product>
 <Product ID="XYZ1234" UserID="XYX" SUperUserID="ROOT" >
   <Name>XYZ1234</Name>
  <Value AttributeID="A">4</Value>
    <Value AttributeID="B">10</Value>
     </Values>
 </Product>
$
0 голосов
/ 18 января 2019

РЕДАКТИРОВАТЬ: В случае, если в соответствии с комментарием ОП, если в строке содержится более чем " значений, я выбираю самое первое значение в диапазоне от " до ".

awk -F'[>"<]' '
/Product ID/{
    match($0,/"[^"]*/)
    val=substr($0,RSTART+1,RLENGTH-1)
}
/<Name>/{
    sub(/>.*</,">"val"<")
}
1'  Input_file

Вывод после запуска вышеуказанного кода выглядит следующим образом:

awk -F'[>"<]' '
/Product ID/{
    match($0,/"[^"]*/)
    val=substr($0,RSTART+1,RLENGTH-1)
}
/<Name>/{
    sub(/>.*</,">"val"<")
}
1'  Input_file
 <Products>
<Product ID="ABC1234" UserID="XYX" SUperUserID="ROOT" >
  <Name>ABC1234</Name>  
  <Values>
    <Value AttributeID="A">1</Value>
    <Value AttributeID="B">00</Value>
     </Values>
</Product>
 <Product ID="XYZ1234" UserID="XYX" SUperUserID="ROOT" >
   <Name>XYZ1234</Name>
  <Value AttributeID="A">4</Value>
    <Value AttributeID="B">10</Value>
     </Values>
 </Product>


Не могли бы вы попробовать следующее.

awk -F'[>"<]' '
/Product ID/{
    match($0,/".*"/)
    val=substr($0,RSTART+1,RLENGTH-2)
}
/<Name>/{
    sub(/>.*</,">"val"<")
}
1' Input_file
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...