grep이 변수의 패턴을 잘못 읽습니다.

grep이 변수의 패턴을 잘못 읽습니다.

이스케이프 패턴을 입력하는 데 문제가 있습니다 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/cccexport_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

관련 정보