Как заменить строку перед совпадением в linux (RHEL7)

На самом деле нет необходимости в awk или sed; bash globbing и тестирование регулярных -выражений могут это сделать:

for d in /tmp/*/*/*
do
  if [[ $d =~ ^/tmp/[^[:space:]]+[[:space:]]([^[:space:]]*).*/([^[:space:]]*).*/([^[:space:]]*) ]]
  then
    printf "%s\n" "${BASH_REMATCH[1]}${BASH_REMATCH[2]}${BASH_REMATCH[3]}"
  fi
done

Пример вывода:

I.01.a.
II.03.d.

Регулярное выражение внутри разбивается на три компонента:

  1. ^/tmp/[^[:space:]]+[[:space:]]([^[:space:]]*).*/

Имя файла должно начинаться ^с /tmp/, затем должно содержать некоторые не-пробельные символы, за которыми следует пробел, за которым следует (захват этих )не-пробельных символов, затем что-либо до вперед -косая черта

  1. ([^[:space:]]*).*/

... за которым следует (захват этого )не -пробела, затем что-либо до косой черты -

  1. ([^[:space:]]*)

... за которым следует (захват этого )не -символа пробела)--за которым следует... ничего, о чем мы заботимся.

Bash сохраняет эти захваченные биты в массив BASH _REMATCH, основываясь на порядке захватываемых скобок.

0
20.03.2020, 16:25
2 ответа

Предполагая, что ваш xml сформирован правильно, вы можете использоватьxmlstarlet

xmlstarlet edit --update \
    '//alarmSpecification[errorCode=444][moduleId="PSC-Task5555"]/@active' --value "no" file1

Выход

<alarmSpecifications>
  <alarmSpecification active="yes">
    <moduleId>PSC-Task1111</moduleId>
    <errorCode>444</errorCode>
  </alarmSpecification>
  <alarmSpecification active="yes">
    <moduleId>PSC-Task2222</moduleId>
    <errorCode>444</errorCode>
  </alarmSpecification>
  <alarmSpecification active="yes">
    <moduleId>PSC-Task3333</moduleId>
    <errorCode>444</errorCode>
  </alarmSpecification>
  <alarmSpecification active="yes">
    <moduleId>PSC-Task4444</moduleId>
    <errorCode>444</errorCode>
  </alarmSpecification>
  <alarmSpecification active="no">
    <moduleId>PSC-Task5555</moduleId>
    <errorCode>444</errorCode>
  </alarmSpecification>
</alarmSpecifications>
1
28.04.2021, 23:20

Пробовал использовать команду «Ниже», все работает нормально

g=`awk 'END{print NR}' test.txt `

for ((i=1;i<=$g;i++)); do j=$(($i+3)); sed -n ''$i','$j'p' test.txt| perl -pne "s/\n/ /g"| awk '/444/&&/PSC-Task5555/{gsub("yes","**no**",$0)}1'; i=$j;echo -e "\n"; done| sed "s/> />\n/g"| sed '/^$/d'

выход

</alarmSpecification>
<alarmSpecification active="yes">
<moduleId>PSC-Task1111</moduleId>
<errorCode>444</errorCode>
</alarmSpecification>
<alarmSpecification active="yes">
<moduleId>PSC-Task2222</moduleId>
<errorCode>444</errorCode>
</alarmSpecification>
<alarmSpecification active="yes">
<moduleId>PSC-Task3333</moduleId>
<errorCode>444</errorCode>
</alarmSpecification>
<alarmSpecification active="yes">
<moduleId>PSC-Task4444</moduleId>
<errorCode>444</errorCode>
</alarmSpecification>
<alarmSpecification active="**no**">
<moduleId>PSC-Task5555</moduleId>
<errorCode>444</errorCode>

Метод2 :Python

#!/usr/bin/python
import re
u=[]
l=re.compile(r'444')
e=re.compile(r'PSC-Task5555')
k=open('test.txt','r')
p=k.readlines()
print len(p)

for o in range(0,len(p),4):
    u.append("".join(p[o:o+4]).replace("\n"," "))

for g in u:
    if re.search(l,g) and re.search(e,g):
        print re.sub("yes","**no**",g).replace("> ",">\n").strip()
    else:
        print g.replace("> ",">\n").strip()

выход

</alarmSpecification>
<alarmSpecification active="yes">
<moduleId>PSC-Task1111</moduleId>
<errorCode>444</errorCode>
</alarmSpecification>
<alarmSpecification active="yes">
<moduleId>PSC-Task2222</moduleId>
<errorCode>444</errorCode>
</alarmSpecification>
<alarmSpecification active="yes">
<moduleId>PSC-Task3333</moduleId>
<errorCode>444</errorCode>
</alarmSpecification>
<alarmSpecification active="yes">
<moduleId>PSC-Task4444</moduleId>
<errorCode>444</errorCode>
</alarmSpecification>
<alarmSpecification active="**no**">
<moduleId>PSC-Task5555</moduleId>
<errorCode>444</errorCode>
0
28.04.2021, 23:20

Теги

Похожие вопросы