여러 파일의 특정 패턴을 바꾸는 방법은 무엇입니까?

여러 파일의 특정 패턴을 바꾸는 방법은 무엇입니까?

내 목표는 아래와 같이 여러 XML 파일의 버전 번호를 업데이트하는 것입니다.

<?xml version="1.0" encoding="UTF-8"?>
<Component xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>51.0</apiVersion>
    enter code here

xml 파일의 버전은 다를 수 있습니다.

<?xml version="1.0" encoding="UTF-8"?>
<Component xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>27.0</apiVersion>
    enter code here

나는 이와 같은 몇 가지 옵션을 시도했습니다.

find force-app -type f -name "*-meta.xml" -exec sed -i '' -e 's/\(<apiVersion>\)\([0-9]+\.0\)\(<\/apiVersion>\)/<apiVersion>52.0<\/apiVersion>/' {} \;

find force-app -type f -name "*-meta.xml" -exec sed -i '' -e '/<apiVersion>/s/\(\d\+\)/52.0/' {} \;

하지만 그 사람들은 직업이 없어

답변1

항상 그렇듯이, XML 파일을 수정하기 위해 줄 기반 텍스트 편집 도구를 사용하고 싶지는 않을 것입니다. XML은 개행으로 구분된 문서 형식이 아닙니다.

/Component/apiVersion단일 XML 문서에서 노드 값을 업데이트하려면 xmlstarlet다음과 같은 방법을 사용하는 것이 좋습니다.

xmlstarlet ed \
    -N x='http://soap.sforce.com/2006/04/metadata' \
    -u '/x:Component/x:apiVersion' -v '52.0' file-meta.xml

XPath 표현식은 이름이 지정된 네임스페이스 ( 문서의 네임스페이스와 일치하도록 정의됨) /x:Component/x:apiVersion에서 업데이트하려는 노드와 일치합니다 . 일반적으로 즉, XML 문서에 네임스페이스가 없으면 여기서 수행한 것처럼 노드 이름 앞에 접두사를 붙일 필요가 없습니다 . 새로운 값은 로 주어진다 .x-N-Nx:-v

다음과 같이 여러 파일을 그 자리에서 편집할 수 있습니다.

xmlstarlet ed --inplace \
    -N x='http://soap.sforce.com/2006/04/metadata' \
    -u '/x:Component/x:apiVersion' -v '52.0' *-meta.xml

또는 다음에서 호출하세요 find.

find force-app -type f -name '*-meta.xml' \
    -exec xmlstarlet ed --inplace \
        -N x='http://soap.sforce.com/2006/04/metadata' \
        -u '/x:Component/x:apiVersion' -v '52.0' {} +

값이 아직 존재하지 않는 경우에만 값을 변경하려면 52.0대신 XPath 표현식을 사용하십시오 /x:Component/x:apiVersion[text() != "52.0"].


xq(XML 파서, 부분 yq, YAML 래퍼 jq, JSON 파서, fromhttps://kislyuk.github.io/yq/):

$ xq -x '.Component.apiVersion |= "52.0"' file.xml
<Component xmlns="http://soap.sforce.com/2006/04/metadata">
  <apiVersion>52.0</apiVersion>
</Component>

답변2

파일이 모두 표시된 것처럼 단순하다면 다음을 수행할 수 있습니다.

find force-app -type f -name "*-meta.xml" \
    -exec sed -i '' -e 's|<apiVersion>[0-9]*[0-9.]*[0-9]*</apiVersion>|<apiVersion>52.0</apiVersion>|' {} \;

Linux에서는 오류가 발생하므로 대신 다음 명령을 사용할 수 있습니다.

find force-app -type f -name "*-meta.xml" \
  -exec sed -i 's|<apiVersion>[0-9]*[0-9.]*[0-9]*</apiVersion>|<apiVersion>52.0</apiVersion>|' {} \;

관련 정보