파일의 문자열 교체

파일의 문자열 교체

다음 파일이 있습니다.

<?xml version="1.0" encoding="utf-8"?>
<!--Generated by crowdin.net-->
  <string name="test" >- test</string>
  <string name="test" >test-test</string>
  <string name="test" >test - test</string>

en dash유니코드 값으로 바꾸고 싶지만 전부는 아니고 string태그 중 하나로 바꾸고 싶습니다.

다른 정규식을 사용하여 몇 가지를 실행했지만 sed알아낼 수 없습니다. 그 중 하나는

sed -i.bak "s/-[^-\<\>0-9]/\&#8211\;/g" strings.xml

출력은 다음과 같습니다

<?xml version="1.0" encoding="utf-8"?>
<!-&#8211;enerated by-->
  <string name="test" >&#8211;test</string>
  <string name="test2" >test&#8211;est</string>
  <string name="test3" >test &#8211;test</string>

내 문제는 나도 교체한다는 것입니다빈 공간그리고첫 번째 문자두 번째 단어 중. 나는 regex및 에 대한 경험이 많지 않습니다 sed. 내가 뭘 잘못하고 있는지 설명해 주실 수 있나요?

참고: 저는 OSX를 사용하고 있습니다.

답변1

가장 가까운 (for \Ks///r) 를 사용 perl하고 <string>태그가 중첩되지 않았다고 가정합니다.

perl -0777 -pi.bak -e's{<string.*?>\K.*?(?=</string>)}{$&=~s/-/&#8211;/rg}ges' file.xml
  • -0777:흡연 모드<string>: 전체 파일을 한 번에 처리합니다( 태그가 여러 줄에 걸쳐 표시되도록 허용 ).
  • -p: sed모델
  • -i.bak: 확장 기능을 사용한 내부 편집 .bak(btw, 여기에서 sed일부 구현에 대한 아이디어가 나왔습니다)
  • s{...}{...}ges: 전역 대체( g). 개행 .문자( s)와도 일치하며 대체를 perl실행할 코드( e)로 처리합니다.
  • <string.*?>\K.*?</string>: is 부분에 태그 자체를 포함하지 않고 from <string...>to와 일치합니다.</string>일치( \K정의하는일치섹션이 시작되고 (?=...)미리보기 연산자입니다.조사하다존재 하지만 </string>일치 항목에 포함되지 않음).
  • $&=~s/.../.../rg. 대체하세요일치부분( $&). 이 r플래그는 실제로 수정되지는 않지만 $&대체된 문자열을 반환합니다.

답변2

휴, 시간이 지나서야 깨달았습니다. 이것은 순진한 해결책입니다.테든의 답변더 정확하게 말하면 그의 :)를 사용해야 합니다.

sed -Ei.bak "s/(.*<string[^>]*\")(.*)-(.*)/\1\2\&#8211;\3/g" strings.xml

나는 사용하고있다역참조이전에 일치된 문자열에 대한 참조입니다. 이것들이 다 \1 \2기다리고 있어

이 경우 sed는 다음 그룹과 일치해야 합니다.

  • (.*<string[^>]*\")- 문자 뒤에 따옴표까지 문자열 토큰이 옵니다 ".그룹 1
  • (.*)- 그룹 3 이후 "(현재 >)까지의 모든 것.그룹 2
  • -일치하는 대시
  • (.*)- 대시 이후의 모든 것과 일치합니다.그룹 3

그런 다음 이전에 일치했던 그룹 및 대시 HTML 값으로 대체 &#8211;하고 그룹에 대한 참조로 \n사용 했습니다 .nn

질문:

현재 몇 가지 문제를 해결하려고 노력하고 있으니 협조해 주시기 바랍니다.

  1. 그룹 1 대회도 마찬가지dsfjpasj<string
  2. 그룹 1에는 문자열 표시 종료 문자가 포함되어야 합니다.>
  3. >1 -terdon이 지적한 대로: "여러 줄에 걸쳐 있는 태그나 태그가 있거나 중첩된 경우에는 작동하지 않습니다."

더 읽어보세요:

http://toytoygogie.blogspot.de/2010/02/using-sed-with-backreference-as.html

답변3

-내가 올바르게 이해했다면 태그 내의 모든 사례(예제에서는 3개) <strng></string>와 해당 사례만 바꾸길 원할 것입니다 . 그렇다면 이 방법이 효과가 있을 것입니다.XML이 정상이라고 가정:

  1. 정규 표현식과 다음과 같은 간단한 도구를 사용하세요.sed

    sed 's/\(<string[^>]*>[^-]*\)-\([^-]*<\/string\)/\1\&#8211;\2/' file.xml 
    
  2. 귀하의 파일이언제나위의 예와 같이 태그가 항상 임을 확신할 수 있습니다 <string name="test" ></string>.검토:

    perl -pe 's/(?<=<string name="test" >)([^<]*?)-([^<]*)/$1&#8211;$2/g' file.xml
    
  3. -태그 내에 태그가 여러 개 있으면 위의 방법 중 어느 것도 작동하지 않습니다. 이 상황을 처리하기 위해 우리가 <string></string>태그 안에 있는지 확인하는 간단한 작은 스크립트를 작성할 수 있습니다 . 중첩된 태그도 처리해야 합니다.

    perl -F'<' -lane 'for($i=0;$i<=$#F;$i++){
        $a++ if $F[$i]=~/^string/; 
        $F[$i]=~s/-/&#8211;/g if $a>0; 
        $a-- if $F[$i]=~/^\/string/
    } print join "<",@F' file.xml
    

관련 정보