주어진 변수 > < 사이의 텍스트를 찾아 텍스트를 다른 것으로 변경합니다.

주어진 변수 > < 사이의 텍스트를 찾아 텍스트를 다른 것으로 변경합니다.

예를 들어 파일을 검색하면. s_webdomain의 file.xml은 다음과 같습니다.

        <hostname oa_var="s_webhost">hostname</hostname>
     <externURL oa_var="s_external_url">https://hostname:4450</externURL>
     <directory_index oa_var="s_directory_index">index.html</directory_index>
     <webentryhost oa_var="s_webentryhost">hostname.host</webentryhost>
     <webentrydomain oa_var="s_webentrydomain">services.uk</webentrydomain>
     <domain oa_var="s_webdomain">services.uk</domain>
     <server_ip_address oa_var="s_server_ip_address"/>
     <!-- Configuration files -->
     <!-- SSL Variables -->
     <url_protocol oa_var="s_url_protocol">http</url_protocol>
     <web_ssl_directory oa_var="s_web_ssl_directory">/u03/app/ENV/gs/inst/ENV_01-bsapp01/certs</web_ssl_directory>
     <local_url_protocol oa_var="s_local_url_protocol">http</local_url_protocol>

나는 services.uk를 대체하고 싶습니다.

<domain oa_var="s_webdomain">SOME_DIFFERENT_TEXT</domain>

$ grep s_webdomain file.xml | awk -F '>' '{print $2}' | awk -F '<' '{print $1}'

영국 서비스 네트워크

services.uk를 SOME_DIFFERENT_TEXT로 변경하는 방법에 대한 아이디어가 있습니까? sed 명령이 필요할 수도 있지만 확실하지 않습니다.

감사해요.

답변1

구조화된 문서 형식의 문서로 작업할 때 가장 좋은 처리 도구는 해당 형식을 인식하는 도구입니다.

다음은 XML 처리 도구를 사용하여 모든 노드의 값을 속성 xmlstarlet으로 값으로 대체합니다.domainou_vars_webdomain

xmlstarlet edit \
    --update '//domain[@oa_var = "s_webdomain"]' \
    --value "SOME_DIFFERENT_TEXT" file

또는 짧은 옵션을 사용하세요.

xmlstarlet ed \
    -u '//domain[@oa_var = "s_webdomain"]' \
    -v "SOME_DIFFERENT_TEXT" file

이 명령은 XPath 쿼리를 사용하여 //domain[@oa_var = "s_webdomain"]업데이트될 입력 문서에서 가능한 모든 위치를 지정합니다. 일치하는 각 엔터티의 값은 (이 경우) string 으로 업데이트됩니다 SOME_DIFFERENT_TEXT.

Xpath 패턴의 첫 번째 문자 는 노드를 찾을 수 있음 //을 나타냅니다.domain어딘가에. 일반적으로 사람들은 문서의 구조를 알고 있으며 처리할 노드에 대한 보다 정확한 경로를 지정합니다.

문서를 "제자리"로 변경하려면 뒤에 --inplace( -L)를 추가하면 됩니다.edit

예를 들어 여러 노드에 영향을 미치려면 webentrynode값은 다음과 같습니다.oa_vars_webentrydomain

xmlstarlet edit \
    --update '//domain[@oa_var = "s_webdomain"]' \
    --value "SOME_DIFFERENT_TEXT" \
    --update '//webentrydomain[@oa_var = "s_webentrydomain"]' \
    --value "SOME_DIFFERENT_TEXT" file

도착하다정제사용할 수 있는 값은 xmlstarlet select다음과 같습니다.

xmlstarlet select \
    --template \
    --value-of '//domain[@oa_var = "s_webdomain"]' \
    -nl file

또는 짧은 옵션을 사용하세요.

xmlstarlet sel -t -v '//domain[@oa_var = "s_webdomain"]' -n file

답변2

awk만 사용할 수 있습니다.

테스트하려면:
awk '{sub(/s_webdomain\">services.uk/,"s_webdomain\">some_new_text"); print}' file.xml

그리고 적절한 위치에 적어주세요:
awk -i inplace '{sub(/s_webdomain\">services.uk/,"s_webdomain\">some_new_text"); print}' file.xml

답변3

예제 문서에는 한 줄의 모든 태그(및 원하는 일치하는 모든 줄)가 포함되어 있으므로 다음과 같은 간단한 Perl 명령을 사용하여 해당 텍스트를 변경하겠습니다.

#
# perl -i.bak -p -e "s/(<.*>)(.*)(<.*>)/\${1}SOME_DIFFERENT_TEXT\${3}/ if /s_webdomain/" file.xml 
#
# diff file.xml file.xml.bak 
10c10
<      <domain oa_var="s_webdomain">SOME_DIFFERENT_TEXT</domain>
---
>      <domain oa_var="s_webdomain">services.uk</domain>
#

간단한 Perl 명령은 *.bak확장자를 가진 백업 파일을 만들고, 지정된 텍스트 파일의 각 줄을 인쇄하고, 정규식을 사용하여 줄을 일치시킨 s_webdomain다음, 가운데 텍스트를 SOME_DIFFERENT_TEXT로 바꾸어 출력 파일을 생성합니다.

Diff 명령은 텍스트 파일의 업데이트된 내용을 백업 파일의 원본 내용과 비교하여 변경된 내용을 표시합니다.

Perl이 이미 설치되어 사용 가능할 수도 있습니다. 이 솔루션은 조정을 통해 매우 빠르고 확장 가능합니다.

관련 정보