입력 파일의 경로를 바꾸려고 합니다.
#include "../../../Plumed.h" #### this is old patch in input
#include "/usr/local/include/Plumed.h #### this should be the new path
이전에 답변한 질문을 본 후(https://stackoverflow.com/questions/11245144/replace-whole-line- Contains-a-string-using-sed).
나는 이것을 시도했다.
sed -i '/../../../Plumed.h/c\/usr/local/include/Plumed.h' ../dist0.xvg
perl -i -pe 's/../../../Plumed.h/usr/local/include/Plumed.h/g' ../dist0.xvg
나는 sed/perl이 혼란스러워지고 있다고 생각하지만 이 문제를 극복하는 방법을 모르겠습니다. 어떤 도움이라도 대단히 감사하겠습니다.
답변1
TL, 박사:
사용:
sed -i 's:"\.\./\.\./\.\./Plumed\.h":"/usr/local/include/Plumed.h":g' ../dist0.xvg
시도한 Sed 명령에 대한 몇 가지 의견:
sed -i '/../../../Plumed.h/c\/usr/local/include/Plumed.h' ../dist0.xvg
-i
이식성이 없으므로 GNU Sed를 사용하고 있는 것 같습니다.BSD Sed
-i
에도 스위치가 있지만 백업 확장자는 필수 매개변수이므로 BSD Sed에 백업을 저장하지 않고 파일을 수정하는 것이 필요하다-i ''
.-i
다른 버전의 Sed에는 스위치가 전혀 없을 수도 있습니다.여기의 정규식에는
/../../../Plumed.h/
정규식 구분 기호의 여러 복사본이 포함되어 있습니다.일반적인 해결책은 구분 기호를 이스케이프 처리하는 것입니다.
/..\/..\/..\/Plumed.h/
그러나 Sed에 대해서는 알려진 사실이 거의 없습니다.어느
s
백슬래시로 첫 번째 인스턴스를 이스케이프하면 정규식 구분 기호입니다(명령뿐만 아니라). (거의 모든 것 - 백슬래시나 개행 문자는 허용되지 않습니다.)인용하다POSIX 사양곧장:
컨텍스트 주소에서 "
\cBREc
"를 구성합니다.씨은<backslash>
또는 를 제외한 모든 문자<newline>
이며 " "와 동일해야 합니다/BRE/
. 지정된 문자인 경우씨뒤에 나타나는 문자<backslash>
는 BRE를 종료하지 않는 리터럴 문자로 처리됩니다. 예를 들어 컨텍스트 주소 "\xabc\xdefx
"에서 두 번째엑스자신을 나타내므로 BRE는 "abcxdef
"입니다.따라서 "기울어진 이쑤시개 증후군"을 방지하려면 다음 두 정규 표현식이 동일하다는 점에 유의하세요.
/..\/..\/..\/Plumed.h/ \:../../../Plumed.h:
내가 "동등하다"고 말했음을 참고하세요아니요옳은. 이것은 다른 답변이 놓친 다음 요점으로 연결됩니다.
정규식의 마침표( )는 다음
.
을 나타냅니다.모든 문자.리터럴 마침표만 일치시키려면 백슬래시를 사용하여 마침표를 이스케이프하거나 에서와 같이 문자 클래스에 붙여 넣을 수 있습니다
[.]
.따라서 리터럴 마침표만 일치시키려면 정규식은 실제로 다음과 같아야 합니다.
\:\.\./\.\./\.\./Plumed\.h:
이쑤시개가 기울어지는 것을 방지하기 위해 너무 많은 것입니다.
아마도 더 읽기 쉬운 형식을 사용할 수도 있습니다.
\:[.][.]/[.][.]/[.][.]/Plumed[.]h:
명령
c
이 변경되었습니다.전선, 정규식과 일치하는 줄 부분만이 아닙니다.s
행의 일부만 변경하려면 이 명령을 사용하십시오 .s
이 명령을 사용하면 주소에 대체 구분 기호를 사용할 때처럼 첫 번째 정규식 구분 기호(구분 기호로 사용되는 특이한 문자의 경우에도)를 이스케이프할 필요가 없다는 점은 주목할 가치가 있습니다 .또한 이
c
명령과 관련하여 같은 줄에 새 텍스트를 포함하는 것은c\
GNU 확장이며 이식성이 없다는 점에 주목할 가치가 있습니다.
s
이 모든 것을 종합하면 다음과 같은 명령을 사용할 수 있습니다 .
sed -i 's:"\.\./\.\./\.\./Plumed\.h":"/usr/local/include/Plumed.h":g' ../dist0.xvg
또는 좀 더 명확하게 하고 싶다면 앵커 정규식과 c
hange 명령을 사용하여 전체 줄을 변경할 수 있습니다.
sed -i '\:^#include "\.\./\.\./\.\./Plumed\.h"$:c\#include "/usr/local/include/Plumed.h"' ../dist0.xvg
답변2
/
구분 기호 로 사용하는 경우 sed
해결책은 다음과 같습니다.
sed -i 's/..\/..\/..\/Plumed.h/\/usr\/local\/include\/Plumed.h/g' file
또는 와 다른 구분 기호를 사용할 수 있습니다 . /
예를 들면 다음과 같습니다.:
sed -i 's:../../../Plumed.h:/usr/local/include/Plumed.h:g' file
또 다른 방법 awk
:
awk '{ gsub("../../../Plumed.h","/usr/local/include/Plumed.h"); print $0}' file
답변3
이 명령은 나에게 효과적입니다.
sed -i 's#include "../../../Plumed.h"#include "/usr/local/include/Plumed.h"#g'
답변4
텍스트에 슬래시가 많으면 느낌표를 사용하세요.
sed -e 's!../../../Plumed.h!/usr/local/include/Plumed.h!'