2014-01-10 4 views
1

텍스트 파일에서 정규식을 검색하려고했는데 일치 범위 내에서 한 문자를 다른 문자로 바꿉니다. 제 문제는 제가 간단한 방법으로는 할 수 없다는 것입니다.정규식 일치 문자 만 바꾸기

예제 소스 파일 :

... 
<br> 
<a id="some shopitem" ref="#some shop item name 01 a" style="text-decoration:none;"><h3 style="background-color: #ccc;">blah blab hasdk sldk sasdas dasda sd</h3></a> 
<table> 
<td width="500"> 
.... 
내가 ("공백 어떤 이름 #"REF =) 정규 표현식 ref=\"#[[:alnum:] ]*\" 일치 할 필요가

거기에 경기에 공백을 대체 -하지만 물론 변화를하지 않습니다 "" 다른 공백이 있거나 정규식이 일치합니다.

그래서 결과를해야 다음과 같습니다

.... 
<br> 
<a id="some shopitem" href="#some-shop-item-name-01-a" style="text-decoration:none;"><h3 style="background-color: #ccc;">blah blab hasdk sldk sasdas dasda sd</h3></a> 
<table> 
<td width="500"> 
.... 

는 그냥 bash는 한 줄의 명령 스크립트의 어떤 종류없이 그것을 할도 수 있을까요? 그룹의 공백을 대체하는 방법이 있습니까? sed -r s/ref=\"#([[:alnum:] ]*\)/(\1s/ /-/g)/g'과 같은 무엇입니까?

답변

0

펄 솔루션 :

perl -pe 's/(ref="#)([\w\s]+)(")/ ($x,$y,$z)=($1,$2,$3); $y =~ s{\s}{-}g; $x.$y.$z /eg' 

그것의 (탭, 다른 공백 문자 밑줄)

0

그것을 할도 수 있을까를 심판 이름에 표시 할 수있는 일에 대해 조금 더 허용 bash의 한 줄 명령으로 스크립트를 작성하지 않고?

당신의 질문이 어떻게 든 나를 이렇게 불타는 야망을 촉발 시켰습니다 ...!

varfile=SOURCEFILE && varsubstfile=RESULTFILE && IFS=' ' read -a repl <<< $(sed -r 's/(.*)(ref="#.*?")(.*)/\2/;tx;d;:x' $varfile | sed -e 's/\ /\-/g' | sed ':a;N;$!ba;s/\s/ /g') && for i in "${!repl[@]}"; do needle["$i"]=$(sed 's/\-/\ /g' <<< "${repl["$i"]}"); done && cp $varfile $varsubstfile && for i in "${!needle[@]}"; do sed -ir "s/${needle[i]}/${repl[i]}/g" $varsubstfile; done && unset needle && unset repl && less $varsubstfile && unset varfile && unset varsubstfile 

SOURCEFILERESULTFILE 출력이 기록됩니다 파일의 이름입니다, 당신은 SourceFile, 그래서 필요에 따라 둘 다의 변경합니다. , 그렇지 않으면했을

은 음 ... 그것은 스크립트의 종류이지만, 그것은 (빌어 먹을 거대한) 한 줄 :) 내가 전체 파일에 ref="#.*" 더 발행 수가 있다는 것을 가정

입니다 훨씬 더 짧다 (비록 내가 더 짧은 버전을 더 이상 기억하지 않지만).

... 내가 정말 당신 * 괜찬아 시스템에서 작동 희망 :

varfile=SOURCEFILE && #set variable for the sourcefile 
varsubstfile=RESULTFILE && #set variable for the resultfile 
IFS=' ' read -a repl <<< #we're going to read multiple values into an array "repl" 
         #delimited by a space 
    $(
    #grab only the second capture group (ref="#.*?") 
    sed -r 's/(.*)(ref="#.*?")(.*)/\2/;tx;d;:x' $varfile | 
    sed -e 's/\ /\-/g' | #replace every space in (ref="#.*?") with a dash 
    sed ':a;N;$!ba;s/\s/ /g' #replace newlines with a space 
    #when there is more than one occurence sed will delimit them with a newline 
    #but i set a space as the delimiter for the read operation, 
    #thus the last replacement 
    ) && 
#we now have every needed replacement-string in an array called "repl" 
for i in "${!repl[@]}"; do #iterate over every value in the array we just read 
    needle["$i"]=$(sed 's/\-/\ /g' <<< "${repl["$i"]}"); #replace dashes with spaces and store in a new variable 
done && 
#and now every original string, the needle we are going to search for 
#is stored in another array 
cp $varfile $varsubstfile && #copy sourcefile to resultfile 
for i in "${!needle[@]}"; do #for every string we are going to replace 
    sed -ir "s/${needle[i]}/${repl[i]}/g" $varsubstfile; #... we replace it! 
done 
#technically we're done here 
#but i like to clean up afterwards and show the result with less 
unset repl && less $varsubstfile && unset varfile && unset varsubstfile 
+0

놀라운 :이 것은 무엇을 알고 싶어 그냥 경우 D


, 여기에 대한 설명입니다 일! 그래서 동정심, perl이 있기 때문에 일을 훨씬 쉽게 할 수 있습니다. 나는 그것이 당신이 bash를 가지고 그것을 할 수 있다는 것을 아주 감명을 줄 때까지 당신의 방법을 해결책으로 표시 할 것입니다. 너는 나의 존경심을 가지고있다. – Jan

+0

난 그냥 재미의 개념으로 그리고 개념의 증거로 이것을했다. "정직한 해결책"을 의미하는 것이 아니며 단지 bash만으로 가능하다는 것을 보여줄뿐입니다. 이 망할 거대한 것은 거의 읽을 수 없으며 예상대로 작동하지 않으면 디버깅하는 데 어려움이 있습니다.) –

관련 문제