큰 따옴표 안에 큰 따옴표를 어떻게 피할 수 있습니까?


287

Bash의 큰 문자열 내에서 큰 따옴표를 어떻게 피할 수 있습니까?

예를 들어, 쉘 스크립트에서

#!/bin/bash

dbload="load data local infile \"'gfpoint.csv'\" into table $dbtable FIELDS TERMINATED BY ',' ENCLOSED BY '\"' LINES TERMINATED BY \"'\n'\" IGNORE 1 LINES"

ENCLOSED BY '\"'큰 따옴표로 올바르게 탈출 할 수는 없습니다 . variable을 사용하고 싶기 때문에 변수에 작은 따옴표를 사용할 수 없습니다 $dbtable.




2
@kenorb 그 질문의 복제본처럼 보이지 않습니다 ...
Mark


@Daenyth 이것은 최종 사용자가 액세스 할 수있는 명령 유형이 아닙니다. 대량로드 스크립트는 일반적으로 신뢰할 수있는 사용자 (예 : 시스템 관리자 또는 개발자)가 서버에서 실행 합니다 . 예. 최종 사용자가의 값을 제어하면 $dbtable위험이 있습니다. 그러나 최종 사용자는 일반적으로 데이터를로드하기 위해 시스템에 SSH를 사용하지 않기 때문에 매우 드문 일입니다.
jpmc26

답변:


285

백 슬래시를 사용하십시오.

echo "\""     # Prints one " character.

9
작동하지 않는. x=ls; if [ -f "$(which "\""$x"\"")" ]; then echo exists; else echo broken; fi;반면에 깨진 부여합니다 ... [ -f "$(which $x)" ]; ...또는 ... [ -f $(which "$x") ]; ...잘 작동합니다. 공백이나 다른 특수 문자로 무언가 $x또는 결과를 줄 때 문제가 발생 $(which "$x")합니다. 해결 방법은의 결과를 유지하기 위해 변수를 사용하고 which있지만 bash가 실제로 따옴표를 이길 수 없거나 내가 잘못하고 있습니까?
Luc

grep -oh "\"\""$counter"\""\w*" in $counter이 변수 인 bash 구문의 일부로 다음을 사용하려고 합니다. 그것은 어떤 생각도 좋아하지 않습니다
Jay D

82

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

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

이미 열린 것을 끝내고 ( ') 이스케이프 한 것을 놓고 ( \') 다른 것을여십시오 ( ').

또는

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

이미 개설 ( ') 을 완료 하고 다른 견적 ( "'")에 따옴표를 넣은 후 다른 개 ( ') 를 열면 됩니다.

더 많은 예 : 작은 따옴표로 묶은 문자열 내에서 작은 따옴표를 이스케이프 처리


1
나는 sh -c "echo '{"key ":"value "}'"를 시도했고 심지어 sh -c "echo '{' '"' 'key' ' "' ':' '"' 'value' ' "' 키와 값이라는 단어를 큰 따옴표로 묶으려는 노력으로 '}' "이 있었지만 두 경우 모두 {key : value}를 받았습니다
Igor Yagolnitser

1
큰 따옴표에는 불필요하게 복잡해 보입니다 .Peter 답변과 같이 echo "abc\"abc"생성하기에 충분합니다 abc"abc.
divenex

2
이 간단한 예에서 실제로는 인용 부호가 복잡한 경우에는이를 수행해야 할 수 있으며 @kenorb의 예는 이러한 경우를 처리하는 방법을 알아내는 데 도움이되었습니다.
prosoitos

63

오늘이 Bash 태그 목록 에이 오래된 문제가 나타나는 이유를 모르겠지만 미래의 연구원을 위해 에코를 필요로하는 문자의 ASCII 코드를 사용하여 탈출을 피할 수 있음을 명심하십시오.

예:

 echo -e "This is \x22\x27\x22\x27\x22text\x22\x27\x22\x27\x22"
 This is "'"'"text"'"'"

\x22큰 따옴표 및 \x27작은 따옴표 의 ASCII 코드 (16 진)입니다 . 마찬가지로 모든 문자를 에코 할 수 있습니다.

위의 문자열을 백 슬래시로 에코하려고하면 지저분한 두 행의 백 슬래시 에코가 필요하다고 가정합니다. :)

변수 할당의 경우 다음과 같습니다.

 $ a=$'This is \x22text\x22'
 $ echo "$a"
 This is "text"

변수가 다른 프로그램에 의해 이미 설정되어있는 경우에도 sed 또는 유사한 도구를 사용하여 큰 따옴표 나 작은 따옴표를 적용 할 수 있습니다.

예:

 $ b="Just another text here"
 $ echo "$b"
 Just another text here
 $ sed 's/text/"'\0'"/' <<<"$b" #\0 is a special sed operator
 Just another "0" here #this is not what i wanted to be
 $ sed 's/text/\x22\x27\0\x27\x22/' <<<"$b"
 Just another "'text'" here #now we are talking. You would normally need a dozen of backslashes to achieve the same result in the normal way.

1
그것은 +1 ~ / .profile에에 PS1 변수를 추가의 문제를 해결하기 때문에 echo 'export PS1='\[\033[00;31m\]${?##0}$([ $? -ne 0 ] && echo \x22 \x22)\[\033[00;32m\]\u\[\033[00m\]@\[\033[00;36m\]\h\[\033[00m\][\[\033[01;33m\]\d \t\[\033[00m\]] \[\033[01;34m\]\w\n\[\033[00m\]$( [ ${EUID} -ne 0 ] && echo \x22$\x22 || echo \x22#\x22 ) '' >> ~/.profile
야신 ElBadaoui

1
이것이 답입니다! 나는 당신을 사랑합니다.
Miguel Rojas Cortés

28

Bash를 사용하면 문자열을 인접하게 배치 할 수 있으며 결국 서로 붙어 있습니다.

그래서 이거:

$ echo "Hello"', world!'

생산

Hello, world!

트릭은 필요에 따라 작은 따옴표와 큰 따옴표를 번갈아 사용하는 것입니다. 불행히도, 그것은 매우 지저분 해집니다. 예를 들면 다음과 같습니다.

$ echo "I like to use" '"double quotes"' "sometimes"

생산

I like to use "double quotes" sometimes

귀하의 예에서 나는 다음과 같이 할 것입니다 :

$ dbtable=example
$ dbload='load data local infile "'"'gfpoint.csv'"'" into '"table $dbtable FIELDS TERMINATED BY ',' ENCLOSED BY '"'"'"' LINES "'TERMINATED BY "'"'\n'"'" IGNORE 1 LINES'
$ echo $dbload

다음과 같은 출력이 생성됩니다.

load data local infile "'gfpoint.csv'" into table example FIELDS TERMINATED BY ',' ENCLOSED BY '"' LINES TERMINATED BY "'\n'" IGNORE 1 LINES

여기서 무슨 일이 일어나고 있는지 알기가 어렵지만 유니 코드 따옴표를 사용하여 주석을 달 수 있습니다. 다음은 bash에서 작동하지 않으며 단지 설명을위한 것입니다.

dbload=' load data local infile "'“ 'gfpoint.csv'” ' " into'“ table $dbtable FIELDS TERMINATED BY ',' ENCLOSED BY '” ' "'“ ' LINES” ' TERMINATED BY "'“ '\n'” ' " IGNORE 1 LINES'

위의 " ''"와 같은 인용 부호는 bash로 해석됩니다. 따옴표 " '는 결과 변수로 끝납니다.

이전 예제와 동일한 처리를 수행하면 다음과 같습니다.

$ echoI like to use' "double quotes"' sometimes


4
Oof ... 그건 못 생겼어
Magic Octopus Urn

17

printf를 확인하십시오 ...

#!/bin/bash
mystr="say \"hi\""

printf를 사용하지 않고

echo -e $mystr

출력 : "hi"라고 말하십시오

printf 사용

echo -e $(printf '%q' $mystr)

출력 : say ""hi \ "


2
참고 printf같은뿐만 아니라 더 많은 문자를 이스케이프 ', ()
데이비드 Pärsson

printf %qeval형식화되지 않은 문자열을 준비 합니다 echo -e.
Charles Duffy

2
printf쓸모없는 사용으로echo 포장 할 이유가 없습니다 . 두 예제 모두 인용이 잘못되었습니다. 올바른 수정은 변수를 큰 따옴표로 묶는 것입니다.
tripleee 2012 년

15

큰 따옴표 문자를 변수로 저장하십시오.

dqt = ' "'
echo "큰 따옴표로 묶은 문자열 안에 큰 따옴표 $ {dqt} X $ {dqt}"

산출:

큰 따옴표로 묶인 문자열 안에 큰 따옴표 "X"

39
배쉬는 정말 최악의 언어입니다
Andy Andy

@ 12oclocker, 당신의 대답은 완전합니다 : D! 특히 "sed"명령과 함께 사용하면 하루를 절약 할 수있었습니다!
Artanis Zeratul 2018 년

11

$ "string"을 사용하십시오.

이 예에서는

dbload = $ "데이터를 로컬 인파 일 \" 'gfpoint.csv'\ "를 테이블 $ dbtable에로드 함 'TERMINATED BY', 'ENCLOSED by'\" 'LINES TERMINATED BY \ "'\ n '\"IGNORE 1 LINES "

참고 ( man 페이지에서 ) :

큰 따옴표로 묶은 문자열 앞에 달러 기호 ($ "string")가 있으면 문자열이 현재 로케일에 따라 변환됩니다. 현재 로케일이 C 또는 POSIX 인 경우 달러 기호는 무시됩니다. 문자열이 번역 및 교체되면 교체는 큰 따옴표로 묶습니다.


3
좋아, 그거 몰랐어
David Kierans

-5

"\"이스케이프 대신 큰 따옴표 앞에 추가하십시오.\

#! /bin/csh -f

set dbtable = balabala

set dbload = "load data local infile "\""'gfpoint.csv'"\"" into table $dbtable FIELDS TERMINATED BY ',' ENCLOSED BY '"\""' LINES TERMINATED BY "\""'\n'"\"" IGNORE 1 LINES"

echo $dbload
# load data local infile "'gfpoint.csv'" into table balabala FIELDS TERMINATED BY ',' ENCLOSED BY '"' LINES TERMINATED BY "''" IGNORE 1 LINES

6
공감 : 왜 질문에 대한 csh답변을 게시 bash합니까? 둘은 완전히 독특하고 호환되지 않습니다.
tripleee 2012 년
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.