이스케이프 패턴을 입력하는 데 문제가 있습니다 grep
.
내 테스트 파일은 다음과 같습니다
export_cc = ${dir}/aaa/bbb/ccc
export_cc = ${dir}/aaa/bbb/eee
export_cc = ${dir}/aaa/bbb/ddd
export_cc = ${dir}/aaa/bbb/fff
export_cc = ${dir}/aaa/bbb/ggg
내가 실행하면 :
~/programming/sandbox $ printf %q 'export_cc = ${dir}/aaa/bbb/ccc'
export_cc\ =\ \$\{dir\}/aaa/bbb/ccc
그런 다음 출력을 grep에 복사하면 다음과 같은 패턴이 나타납니다.
~/programming/sandbox $ grep export_cc\ =\ \$\{dir\}/aaa/bbb/ccc file
export_cc = ${dir}/aaa/bbb/ccc
그러나 패턴을 변수나 백틱에 넣으면 다음과 같은 결과를 얻습니다.
~/programming/sandbox $ grep `printf %q 'export_cc = ${dir}/aaa/bbb/ccc'` file
grep: Trailing backslash
grep
이것이 왜 차이를 만드는지, 그리고 인용된 문자열을 변수의 패턴 으로 사용하는 방법을 말해 줄 수 있는 사람이 있습니까 ?
답변1
문제는쉘 탈출. \
는 쉘의 특수 문자이며 grep
.
존재하다:
grep export_cc\ =\ \$\{dir\}/aaa/bbb/ccc file
export_cc\ =\ \$\{dir\}/aaa/bbb/ccc
export_cc = ${dir}/aaa/bbb/ccc
에 전달되기 전에 쉘에 의해 문자열로 해석됩니다 grep
. 당신은 그것을 사용할 수 있습니다스트레스가서 확인해 보세요:
$ strace grep export_cc\ =\ \$\{dir\}/aaa/bbb/ccc file
execve("/bin/grep", ["grep", "export_cc = ${dir}/aaa/bbb/ccc",...
그리고명령 대체:
grep `printf %q 'export_cc = ${dir}/aaa/bbb/ccc'` file
큰따옴표가 없으면 결과는 다음과 같습니다.명령 대체예전에는분할 및 와일드카드쉘은 export_cc\
, =\
, 및 의 세 부분으로 나뉩니다 \$\{dir\}/aaa/bbb/ccc
. 셸은 이를 세 개의 문자열로 처리하여 모든 백슬래시를 이스케이프 처리하고 , , : grep
로 전달합니다.export_cc\\
=\\
\\$\\{dir\\}/aaa/bbb/ccc
$ strace grep $(printf %q 'export_cc = ${dir}/aaa/bbb/ccc') file
execve("/bin/grep", ["grep", "export_cc\\", "=\\", "\\$\\{dir\\}/aaa/bbb/ccc",...
grep
백슬래시 export_cc\
뒤에 아무 것도 없는 패턴을 수신하면 메시지가 표시됩니다 Trailing backslash
.
작동하려면 다음이 필요합니다.큰따옴표 명령 대체, 그리고 사용인쇄 기능%s
대신 사용하십시오 %q
:
$ grep "$(printf %s 'export_cc = ${dir}/aaa/bbb/ccc')" file
export_cc = ${dir}/aaa/bbb/ccc