Совпадение нескольких строк в нескольких строках, а также замена нескольких строк - PullRequest
0 голосов
/ 18 апреля 2020

Я хочу заменить все строки с DISPLAY = "TRUE" на DISPLAY = "FALSE" в первой строке и наоборот в следующей строке в одном совпадении.

Пример: FROM:

 <SYN DISPLAY="TRUE" SEARCH="TRUE" CLASSIFY="TRUE">Appels</SYN>
 <SYN DISPLAY="FALSE" SEARCH="FALSE" CLASSIFY="TRUE">103.103117.1031171012</SYN>

TO

 <SYN DISPLAY="FALSE" SEARCH="TRUE" CLASSIFY="TRUE">Appels</SYN>
 <SYN DISPLAY="TRUE" SEARCH="FALSE" CLASSIFY="TRUE">103.103117.1031171012</SYN>

Обратите внимание, что все другие строки в соответствующей строке <SYN DISPLAY="TRUE" or <SYN DISPLAY="FALSE" могут отличаться.

Требуется сопоставлять и заменять только в появление обеих строк (показано выше), т.е. когда <SYN DISPLAY="TRUE" находится в 1-й строке, а <SYN DISPLAY="FALSE" во второй строке. Отдельные строки со следующим примером шаблона не следует заменять.

<DIMENSION_NODE>
            <DVAL TYPE="EXACT">
               <DVAL_ID ID="4294960976"/>
               <SYN DISPLAY="TRUE" SEARCH="TRUE" CLASSIFY="TRUE">2</SYN>
            </DVAL>
         </DIMENSION_NODE>
    ```


Я пытался использовать sed, однако не смог заставить его работать.

sed -E 's/(<SYN DISPLAY=\")TRUE(\".+\s+<SYN DISPLAY=\")FALSE(\".+<\/SYN>)/\1FALSE\2TRUE\3/' test.xml

Запрос экспертов поможет сделать это работает :) 1020 *

Ответы [ 2 ]

1 голос
/ 18 апреля 2020

При -z переводы строк будут обрабатываться как обычные символы:

sed -zr 's/(SYN DISPLAY=)("TRUE")([^\n]*)\n([^\n]*)SYN DISPLAY=("FALSE")/\1\5\3\n\4\1\2/g' inputfile

В вашем примере запомненные строки:

\1=SYN DISPLAY=
\2="TRUE"
\3= SEARCH="TRUE" CLASSIFY="TRUE">Appels</SYN>
\4= <
\5="FALSE"

Обе строки используются для совпадения, одна строка не будет изменена.

1 голос
/ 18 апреля 2020

С моей точки зрения, самый простой способ достичь этого, если вы не хотите вдаваться в сложные регулярные выражения, это использовать временное значение, например:

sed \
    -e 's/DISPLAY="TRUE"/TMP/g' \
    -e 's/DISPLAY="FALSE"/DISPLAY="TRUE"/g' \
    -e 's/TMP/DISPLAY="FALSE"/g' YOUR_FILE

или, как однострочник:

sed -e 's/DISPLAY="TRUE"/TMP/g' -e 's/DISPLAY="FALSE"/DISPLAY="TRUE"/g' -e 's/TMP/DISPLAY="FALSE"/g' YOUR_FILE
...