makefile에서 sed 사용하기

makefile에서 sed 사용하기

makefile에서 cygwin 경로를 Windows 경로로 변경하고 싶습니다. 이를 위해 나는 사용하고 있습니다

CURDIR := `pwd`
WINDIR := $(shell echo $(CURDIR) | sed -e "s/\/cygdrive\/\(.\)/\1:/" | sed -e 's/\//\\/g')

gnumake를 사용하여 이 makefile을 실행하면 다음 오류가 발생합니다.

sed.exe: -e expression #1, char 8: Unterminated `s' command

그러나 cygwin 쉘에서 직접 다음 명령을 실행하면 원하는 출력을 얻습니다.

$: pwd | sed -e "s/\/cygdrive\/\(.\)/\1:/" | sed -e 's/\//\\/g'

위 명령은 셸에서 아무런 불만 없이 잘 실행됩니다. 이 문제가 발생한 이유는 무엇이며 가능한 해결 방법은 무엇입니까?

답변1

보고 있는 문제를 설명하기 위해 두 번째 sed명령을 사용하면 문제가 발생합니다.

sed -e 's/\//\\/g'

make\이스케이프에 사용할 수 있는 특수 문자 %및 (단일 백슬래시) \\로 변환할 수 있는 이스케이프 시퀀스 역할을 합니다.\

%백슬래시는 두 개 이상의 연속적인 백슬래시가 뒤따르는 경우를 제외하고 그대로 보존되므로 문제를 일으키지 않고 \/유지됩니다 (이것이 문제를 일으키는 유일한 장소인 이유입니다).\/

따라서 sed실행되는 실제 명령은 다음과 같습니다.

sed -e 's/\//\/g'

예를 들어, 다른 구분 기호를 사용하면 명령이 어떻게 불완전한지 확인하는 것이 더 쉽습니다 #.

sed -e 's#/#/g'

첫째, #닫는 구분 기호(이 경우)가 누락되었습니다. 게다가 대체 결과는 예상된 a /대신 a가 됩니다.\

추가 백슬래시를 추가하여 문제를 해결할 수 있습니다(또는 두 개도 가능).

sed -e 's/\//\\\/g'

하지만 이 코드를 읽는 사람에게는 이것이 이상하게 보일 수 있으므로 무슨 일이 일어나고 있는지 설명하기 위해 주석을 추가하는 것이 좋습니다.

또 다른 좋은 아이디어는 두 배로 늘리는 것입니다.모든make백슬래시를 사용하여 레이어 중 하나를 이스케이프 시퀀스로 명시적 으로 사용합니다.

sed -e 's/\\//\\\\/g'

아, 여전히 안 좋네요... Except 이외의 구분 기호를 사용하면 #도움이 될 수 있지만 아마도 그다지 많지는 않을 것입니다.

sed -e 's#/#\\\\#g'

여기에서 사용하는 특정 사례 sed, 즉 Cygwin 경로를 Windows 경로로 변환하는 경우 실제로 사용할 수 있습니다.cygpath --windows, @HaiVu가 댓글에서 지적했듯이.

관련 정보