2009-12-22 2 views
0

내가 인스턴스를 찾는 내가 1에 사용할 수있는 나오지도 스크립트를) 원하는 (스트럿츠에서 EL 구문을 JSTL하기), 2)이 문자열을 인쇄 :.jsp 파일 내에서 찾기/바꾸기를위한 Sed 스크립트.

<bean:write name='iframesrcUrl'/> 
<bean:write name="iframesrcUrl"/> 
<bean:write name="currentPage" property="title" filter="false"/> 

또는 유사한. nameproperty 값이 다를 수 있습니다. propertyfilter 속성은 선택 사항입니다. 작은 따옴표는 모두 '이며 큰 따옴표는 "입니다.

sed 명령은 두 개가되어야합니다. 먼저 발견 된 명령을 보려면 하나의 명령을 실행하고 싶습니다. 다음 실제 교체를 수행하려면 다음 명령을 실행하고 싶습니다. grep '<bean:write name=' **/* |wc -l

것은 무엇이 문제를 해결하는 가장 쉬운 방법이 될 것이다 : 내 프로젝트에서 68 회 발생이 있습니다 보여줍니다

${ iframesrcUrl } 
${ currentPage.title } 

빠른 그렙 : 문자열로 대체되어야 하는가?

답변

1

이 부분적으로 내 질문에 덮여 다른 답변에서 배운 데, 나는 다음과 함께 끝났다.

는 몇 가지 교훈

#my try to find every occurence of constructions like 
# <bean:write name='iframesrcUrl'/> 
# <bean:write name="iframesrcUrl"/> 
# <bean:write name="currentPage" property="title" filter="false"/> 
# 
# or similar. name and property values can differ. property and filter attributes are optional. 
# Both single quotes ' and double quotes " occur. 
# 
# cd jahia_virk/tomcat/webapps/ROOT/jsp/jahia/templates/virk/virk.dk 


# Printing occurences: 
# ===================== 
sed -nE \ 
-e '/<bean:write name="([[:alpha:]]+)"(property="([[:alpha:]]+)")(filter="false")?\/>/p' \ 
-e "/<bean:write name='([[:alpha:]]+)'(property='([[:alpha:]]+)')(filter='false')?\/>/p" \ 
-e '/<bean:write name="([[:alpha:]]+)"\/>/p' \ 
-e "/<bean:write name='([[:alpha:]]+)'\/>/p" \ 
*.jsp **/*.jsp **/*.inc 


# Replacing occurences: 
# ===================== 
sed -E -i .bak \ 
-e 's/<bean:write name="([[:alpha:]]+)"(property="([[:alpha:]]+)")(filter="false")?\/>/${ \1.\3 }/g' \ 
-e "s/<bean:write name='([[:alpha:]]+)'(property='([[:alpha:]]+)')(filter='false')?\/>/\${ \1.\3 }/g" \ 
-e 's/<bean:write name="([[:alpha:]]+)"\/>/${ \1 }/g' \ 
-e "s/<bean:write name='([[:alpha:]]+)'\/>/\${ \1 }/g" \ 
*.jsp **/*.jsp **/*.inc 

같은 구조의 모든 선두로부터를 찾을 수 내 시도 (나는 그것을 짧게 할 수 있지만 그것이 작동 내기)을 배운 :

  • $가에서 예약되어 있습니다 명령 줄이므로 $ sed 표현식이 큰 따옴표 안에있는 줄을 벗어나야 만했습니다.
  • \w은 어떤 단어 문자와도 일치하지 않았습니다. 그래서 나는 대체해야만했습니다 [[:alpha:]]
  • 어떤 디렉토리 (*/* **/*)에있는 파일에서의 대체는 숨겨진 시스템 파일, 이미지와 같은 바이너리 파일 등을위한 것입니다. 저는 .jsp와 .jsp에만 집중해야했습니다.inc 프로젝트에 대한 내 프로젝트 : *.jsp **/*.jsp **/*.inc

한 가지 더주의해야 할 점은 프로젝트에서 오래된 학교 스트럿츠 스타일을 멀리 옮겨야한다는 것입니다. 유사한 상황에 처한 경우 나중에 편집을 신중하게 검토하십시오.

스크립트 단점 : [[:alpha:]]- 일치하지 않았기 때문에 하나가 실패

<bean:write name='scriptEditor-Url'/>  
<bean:write name='currentSite' property='homePage.url'/> 
<bean:write name="portlet" property="value" filter="false" /> 
<bean:write name='<%= "optTextUrl" + id %>'/> 

# (밑줄과 일부도 있습니다) : 여러 가지 이유를 들어 다음 예는 스크립트 위 발견되지 않았다 .

# 2는 동일합니다. [[:alpha:]]은 점 .과 일치하지 않습니다.

# 4는 매개 변수 이름 안에 문자열을 연결합니다. 스크립트를 작성하여 찾을 수는 있지만 프로젝트에 4 번만 발생합니다. 큰 문제는 그것이 대체되어야하는 것입니다. 인라인 자바가 작동하지 않는다고 생각합니다. 그리고 당신이이 sed 명령을 교체 할 수

<root> 
<bean:write name='iframesrcUrl'/> 
<bean:write name="iframesrcUrl"/> 
<bean:write name="currentPage" property="title" filter="false"/> 
<foo><bar/></foo> 
</root> 

같은 파일을 가지고 난 그냥 (GNU가 나오지 사용) ${ 'optTextUrl' + id }

0

나는 그것이

sed '/<bean:write name=/!d' 

2)가

sed '/<bean:write name=/s/^.*$/${ iframesrcUrl }\n${ currentPage.title }/' 

귀하의 질문에 더 찾고 발견 어떤 대체 무엇을 발견 인쇄 여기

1) 그렙 정규식 떨어져거야 ** (*/* glob로 인해) globstar를 사용하여 Bash4를 사용하는 것으로 보입니다. 당신이이 나오지 스크립트는 각 파일을 실행하려면 재귀 내가 제안 : 교체 나오지 스크립트를 들어

#!/bin/bash 

for file in **/*; do 
    <sed one-liner here> "$file" 
done 

, 단지 현재 위치에서 편집 할 -i를 추가합니다. 이를 위해서는 GNU sed가 작동해야합니다. GNU sed가 없다면 출력을 임시 파일로 리디렉션해야합니다.

+0

감사합니다. 커맨드 라인에서 큰 따옴표와 큰 따옴표를 일치시키는 것이 꽤 어렵다는 것을 알았습니다. 그러나 두 표현을 사용하고 sed에 둘 다주는 방법으로 해결할 수 있습니다. –

0

출력 내용이 정확하지 않습니다. 단지 추측 당신이 더 명확 샘플 입력을 제공 할 때까지 출력

awk '/bean:write name/{ 
    $0="${ iframesrcUrl }\n${ currentPage.title }" 
}{print}' file 
+0

예를 들어 감사합니다. 위의 예에서와 같이 진보 된 것을 완전히 이해하지 못하기 때문에 Awk은 여전히 ​​나를 깜짝 놀라게합니다. 지금은 sed 버전을 고집합니다. –

+0

awk 스크립트는 "bean : write name"이 발견되면 해당 행을 "$ {iframesrcUrl} \ n $ {currentPage.title}"으로 변경해야한다고 말합니다. \ n은 개행 문자입니다. 그런 다음 레코드를 인쇄하십시오. 그게 다야. – ghostdog74

0

가정을 쓸 수 없습니다 의심 : 생산하는

sed "s/<bean:write name=[\'\"]\?iframesrcUrl[\'\"]\?\/>/\${ iframesrcUrl }/g; \ 
     s/<bean:write name=[\'\"]\?currentPage[\'\"]\?.*\/>/\${ currentPage.title }/g;" \ 
    input.xml 

:

<root> 
${ iframesrcUrl } 
${ iframesrcUrl } 
${ currentPage.title } 
<foo><bar/></foo> 
</root> 

필요한 것은 무엇입니까? 또는 속성 값을 대체 하시겠습니까? 아니면이 태그에 대체 텍스트를 넣으시겠습니까? 찾아 자리에서 모든 파일을 편집하려면

(!주의는 파일, 사용하기 전에 -i없이 테스트 해 '* .jsp로'대신 파일 마스크를 넣어 변경) :

find . -type f -name '*.jsp' -print0 | xargs -0 sed -i "..." 

UPDATE를

파일 자체가 아닌 속성 값을 바꾸려면 sed/awk 대신 xmlstarlet을 사용하는 것이 좋습니다. 그것은 훨씬 더 신뢰성 있고 유연합니다. xmlstarlet 프로세스에 대한 완전한 (유효) 파일을 필요로하기 때문에, 당신의 경우에 정확히 솔루션을 게시 할 수 없습니다,하지만이 아이디어입니다 :

<a> 
    <b> 
     <c name="foo"/> 
     <c name="bar"/> 
    </b> 
</a> 

하자 우리가 SPAMfoo 교체 싶은 말 :

파일을 감안할 때 및 barEGGS.

$ printf '<a><b><c name="foo"/><c name="bar"/></b></a>' | \ 
    xmlstarlet ed --update "//c[@name='foo']/@name" -v SPAM \ 
       --update "//c[@name='bar']/@name" -v EGGS 
<?xml version="1.0"?> 
<a> 
    <b> 
    <c name="SPAM"/> 
    <c name="EGGS"/> 
    </b> 
</a> 

I 그것이 어떤 c 태그에 속하는 foo 같다 name 속성 첫 번째 경우 (대체 된 요소를 선택하는 구문 XPath를 사용 : 다음 명령은 (가독성을위한 스플릿 선)을 수행 할). ed 부속 명령 xmlstarlet은 다양한 변환을 허용하며 요소를 대체 (업데이트)하는 것은 그 중 하나입니다.

실제의 예에서 당신은 즉,도 bean 작업 공간을 지정 xmlstarlet의 옵션 목록에

-N bean=urn:... 

같은 것을 추가해야합니다. .jsp 파일의 첫 번째 줄에서 정확한 URI를 찾을 수 있습니다 (나는 볼 필요가 없습니다).

+0

영감을주는 아이디어에 감사드립니다. 짐작할 수 있듯이 속성 값을 바꾸려고했습니다. 모든 부분을 버전 화 했으므로 적절한 부분은 꽤 사소한 것이므로 실제 변경 내용을 쉽게 추적 할 수 있습니다. –

+0

그러면 xmlstarlet을 사용하는 것이 좋습니다. 몇 분 안에 예제를 게시 할 것입니다. – sastanin