입력 파일의 경로를 바꾸려고 합니다.
#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,dr:
사용:
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
명령을 사용하면 주소에서 대체 구분 기호를 사용할 때처럼 첫 번째 정규식 구분 기호(구분 기호로 사용되는 특이한 문자의 경우에도)를 이스케이프할 필요가 없습니다.또한 명령과 관련하여 동일한 줄에 새 텍스트를 포함하는 것은 GNU 확장이며 이식성이 없다는
c
점을 아는 것이 좋습니다 .c\
이 모든 것을 종합하면 다음과 같은 명령을 사용할 수 있습니다 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!'