[bash] 작은 따옴표로 묶은 문자열 내에서 작은 따옴표를 이스케이프 처리하는 방법

Bash가 있다고 가정 해 보겠습니다 alias.

alias rxvt='urxvt'

잘 작동합니다.

하나:

alias rxvt='urxvt -fg '#111111' -bg '#111111''

작동하지 않으며 둘 다 작동하지 않습니다.

alias rxvt='urxvt -fg \'#111111\' -bg \'#111111\''

따옴표를 이스케이프하면 문자열 내에서 여는 따옴표와 닫는 따옴표를 어떻게 일치 시키는가?

alias rxvt='urxvt -fg'\''#111111'\'' -bg '\''#111111'\''

그렇게 연결하면 허용되는 경우 동일한 문자열을 나타내더라도 좋지 않은 것처럼 보입니다.



답변

가장 바깥층에 작은 따옴표를 사용하려면 두 종류의 따옴표를 붙일 수 있습니다. 예:

 alias rxvt='urxvt -fg '"'"'#111111'"'"' -bg '"'"'#111111'"'"
 #                     ^^^^^       ^^^^^     ^^^^^       ^^^^
 #                     12345       12345     12345       1234

다음 '"'"'과 같이 해석되는 방법 에 대한 설명 ':

  1. ' 작은 따옴표를 사용하는 첫 번째 따옴표를 종료하십시오.
  2. " 큰 따옴표를 사용하여 두 번째 견적을 시작하십시오.
  3. ' 인용 문자.
  4. " 큰 따옴표를 사용하여 두 번째 견적을 종료하십시오.
  5. ' 작은 따옴표를 사용하여 세 번째 견적을 시작하십시오.

(1)과 (2) 또는 (4)와 (5) 사이에 공백을 두지 않으면 쉘은 해당 문자열을 하나의 긴 단어로 해석합니다.


답변

나는 항상 포함 된 각 작은 따옴표를 시퀀스로 바꿉니다 : '\''즉 따옴표 백 슬래시 따옴표는 문자열을 닫고 이스케이프 된 작은 따옴표를 추가하고 문자열을 다시 엽니 다.


필자는 종종 Perl 스크립트에서 “quotify”기능을 사용하여이 기능을 수행합니다. 단계는 다음과 같습니다.

s/'/'\\''/g    # Handle each embedded quote
$_ = qq['$_']; # Surround result with single quotes.

이것은 거의 모든 경우를 처리합니다.

당신이 소개하면 인생은 더 재미있어 eval쉘 스크립트 . 본질적으로 모든 것을 다시 인용해야합니다!

예를 들어, 위의 명령문을 포함하는 quotify라는 Perl 스크립트를 작성하십시오.

#!/usr/bin/perl -pl
s/'/'\\''/g;
$_ = qq['$_'];

그런 다음 이것을 사용하여 올바르게 인용 된 문자열을 생성하십시오.

$ quotify
urxvt -fg '#111111' -bg '#111111'

결과:

'urxvt -fg '\''#111111'\'' -bg '\''#111111'\'''

그런 다음 alias 명령으로 복사 / 붙여 넣을 수 있습니다.

alias rxvt='urxvt -fg '\''#111111'\'' -bg '\''#111111'\'''

(eval에 명령을 삽입해야하는 경우 quotify를 다시 실행하십시오.

 $ quotify
 alias rxvt='urxvt -fg '\''#111111'\'' -bg '\''#111111'\'''

결과:

'alias rxvt='\''urxvt -fg '\''\'\'''\''#111111'\''\'\'''\'' -bg '\''\'\'''\''#111111'\''\'\'''\'''\'''

이것은 평가판에 복사 / 붙여 넣을 수 있습니다.

eval 'alias rxvt='\''urxvt -fg '\''\'\'''\''#111111'\''\'\'''\'' -bg '\''\'\'''\''#111111'\''\'\'''\'''\'''


답변

Bash 2.04 구문은 $'string'(단지 'string'; 경고 :와 혼동하지 마십시오 $('string')) ANSI C와 같은 이스케이프 시퀀스 를 허용 하고 작은 따옴표 버전으로 확장 할 수있는 또 다른 인용 메커니즘입니다 .

간단한 예 :

  $> echo $'aa\'bb'
  aa'bb

  $> alias myvar=$'aa\'bb'
  $> alias myvar
  alias myvar='aa'\''bb'

귀하의 경우 :

$> alias rxvt=$'urxvt -fg \'#111111\' -bg \'#111111\''
$> alias rxvt
alias rxvt='urxvt -fg '\''#111111'\'' -bg '\''#111111'\'''

일반적인 이스케이프 시퀀스는 예상대로 작동합니다.

\'     single quote
\"     double quote
\\     backslash
\n     new line
\t     horizontal tab
\r     carriage return

다음은 man bash(버전 4.4)의 관련 문서를 복사하여 붙여 넣은 것입니다 .

$ ‘string’형식의 단어는 특별히 취급됩니다. ANSI C 표준에 지정된대로 백 슬래시 이스케이프 문자를 바꾸어 단어를 문자열로 확장합니다. 백 슬래시 이스케이프 시퀀스가있는 경우 다음과 같이 디코딩됩니다.

    \a     alert (bell)
    \b     backspace
    \e
    \E     an escape character
    \f     form feed
    \n     new line
    \r     carriage return
    \t     horizontal tab
    \v     vertical tab
    \\     backslash
    \'     single quote
    \"     double quote
    \?     question mark
    \nnn   the eight-bit character whose value is the octal
           value nnn (one to three digits)
    \xHH   the eight-bit character whose value is the hexadecimal
           value HH (one or two hex digits)
    \uHHHH the Unicode (ISO/IEC 10646) character whose value is
           the hexadecimal value HHHH (one to four hex digits)
    \UHHHHHHHH the Unicode (ISO/IEC 10646) character whose value
               is the hexadecimal value HHHHHHHH (one to eight
               hex digits)
    \cx    a control-x character

확장 된 결과는 달러 기호가없는 것처럼 작은 따옴표로 묶습니다.


자세한 내용 은 bash-hackers.org 위키에서 따옴표 및 이스케이프 : ANSI C와 유사한 문자열 을 참조하십시오. 또한 “Bash Changes” 파일 ( 여기서는 개요 )에는 $'string'인용 메커니즘 과 관련된 변경 및 버그 수정에 대한 내용이 많이 언급되어 있습니다 .

unix.stackexchange.com에 따르면 일반 문자로 특수 문자를 사용하는 방법은 무엇입니까? bash, zsh, mksh, ksh93 및 FreeBSD 및 busybox sh에서 (일부 변형 사용) 작동해야합니다.


답변

나는 그의 블로그 (link pls?)에 항목을 볼 수 없지만 gnu 참조 매뉴얼 에 따르면 :

작은 따옴표 ( ” ‘)로 문자를 묶으면 따옴표 안에 각 문자의 리터럴 값이 유지됩니다. 백 슬래시가 앞에 있어도 작은 따옴표 사이에는 작은 따옴표가 없을 수 있습니다.

bash는 이해할 수 없습니다.

alias x='y \'z '

그러나 큰 따옴표로 묶으면이 작업을 수행 할 수 있습니다.

alias x="echo \'y "
> x
> 'y


답변

'\''작은 따옴표로 묶은 문자열 내에서 작은 따옴표 를 사용 하는 것이 Bash에서 작동한다는 것을 확인할 수 있으며 스레드의 앞부분에 나오는 “접착제”인수와 같은 방식으로 설명 할 수 있습니다. 따옴표로 묶인 문자열이 있다고 가정 'A '\''B'\'' C'합니다 (여기의 모든 따옴표는 작은 따옴표입니다). 에코로 전달되면 다음을 인쇄합니다 A 'B' C.. 각각 '\''의 첫 번째 따옴표는 현재 작은 따옴표로 묶인 문자열을 닫고, 다음 \'은 작은 따옴표를 이전 문자열에 붙이고 ( \'따옴표로 묶은 문자열을 시작하지 않고 작은 따옴표를 지정하는 방법 임) 마지막 따옴표는 다른 작은 따옴표로 묶인 문자열을 엽니 다.


답변

이스케이프 된 작은 따옴표 문자 (\ ‘)를 사용하여 연결하거나 작은 따옴표 문자를 큰 따옴표 ( “‘”)로 묶어 연결하면 두 버전 모두 작동합니다.

질문의 저자는 마지막 탈출 시도 끝에 추가 작은 따옴표 ( ‘)가 있음을 알지 못했습니다.

alias rxvt='urxvt -fg'\''#111111'\'' -bg '\''#111111'\''
           │         │┊┊|       │┊┊│     │┊┊│       │┊┊│
           └─STRING──┘┊┊└─STRIN─┘┊┊└─STR─┘┊┊└─STRIN─┘┊┊│
                      ┊┊         ┊┊       ┊┊         ┊┊│
                      ┊┊         ┊┊       ┊┊         ┊┊│
                      └┴─────────┴┴───┰───┴┴─────────┴┘│
                          All escaped single quotes    │
                                                       │
                                                       ?

이전의 멋진 ASCII / 유니 코드 아트에서 볼 수 있듯이 마지막 이스케이프 된 작은 따옴표 (\ ‘) 뒤에 불필요한 작은 따옴표 (‘)가옵니다. Notepad ++에있는 것과 같은 구문 강조 표시를 사용하면 매우 도움이 될 수 있습니다.

다음과 같은 다른 예에서도 마찬가지입니다.

alias rc='sed '"'"':a;N;$!ba;s/\n/, /g'"'"
alias rc='sed '\'':a;N;$!ba;s/\n/, /g'\'

이 두 개의 아름다운 별칭 인스턴스는 파일을 어떻게 정리할 수 있는지 매우 복잡하고 난독 한 방식으로 표시됩니다. 즉, 줄이 많은 파일에서 이전 줄의 내용 사이에 쉼표와 공백이있는 한 줄만 얻습니다. 이전 주석을 이해하기 위해 다음은 예입니다.

$ cat Little_Commas.TXT
201737194
201802699
201835214

$ rc Little_Commas.TXT
201737194, 201802699, 201835214


답변

쉘에서 따옴표를 이스케이프 처리하는 간단한 예 :

$ echo 'abc'\''abc'
abc'abc
$ echo "abc"\""abc"
abc"abc

이미 열린 하나 ( ') 를 마무리하고 이스케이프 된 하나 ( \')를 배치 한 다음 다른 하나를 열면 ( ') 완료됩니다. 이 구문은 모든 명령에 적용됩니다. 첫 번째 답변과 매우 비슷한 접근 방식입니다.