grep apple 파일과 grep“apple”파일의 차이점은 무엇입니까?


22

차이점은 무엇이며 grep apple file그리고 grep "apple" file? 따옴표를 사용하면 무엇을합니까? 둘 다 작동하고 똑같은 일을합니다 (같은 줄 표시).

답변:


45

인용 부호는 쉘이 특수한 것으로 간주하고 구문 상 의미를 갖는 문자에 영향을줍니다. 귀하의 예에서는 apple이러한 문자가 포함되어 있지 않으므로 차이 가 없습니다.

: 그러나 또 다른 예를 살펴 grep apple tree file단어를 검색합니다 apple파일에서 tree하고 file있는 반면, grep "apple tree" file단어를 검색합니다 apple tree파일에 file. 인용 부호는 bash에 단어 공간 "apple tree"이 새 매개 변수를 시작하지 않지만 현재 매개 변수의 일부 여야 함을 나타냅니다. bash에게 다음 문자의 특별한 의미를 무시하고 문자 그대로 취급하도록 지시 grep apple\ tree file하기 때문에 동일한 결과를 생성합니다 \.


2
와일드 카드에서도 볼 수 있습니다. 당신이 경우에 grep a*b equations.txt그것은를 검색합니다 a*bB로 끝나는 거기에 현재 디렉토리의 시작에있는 파일이며,하지 않는 경우에 그렙가 호출 될 것이다 (때문에 (바) 쉬 명령 행에 파일 이름을 확장합니다), 다른 매개 변수를 완성하여 다른 결과를 얻습니다. find . -name *.txt현재 디렉토리에 txt 파일이있는 경우 와 같은 명령 으로 예기치 않은 동작이 발생하기 때문에 일반적으로 find와 관련된 문제가 더 많습니다 . 이 경우 따옴표를 사용하는 것이 좋습니다.
SztupY

4
또 다른 중요한 점은 큰 따옴표 ( ")와 작은 따옴표 ( ')의 차이입니다. 작은 따옴표는와 같은 특정 문자의 해석을 방지 $하는 반면 큰 따옴표는 해석을 허용합니다. 예는 grep '${USER}'텍스트를 찾습니다 ${USER}반면, grep "${USER}"변수가있는 텍스트를 찾습니다 USER포함 (예를 들면 johnstacen).
Paddy Landau

23

큰 따옴표는 평가를 허용하고 작은 따옴표는 평가를 방지하며 따옴표는 명령 줄에서 사용될 때 와일드 카드 확장을 허용하지 않습니다. 고안된 예로서 :

[user@work test]$ ls .
A.txt B.txt C.txt D.cpp

# The following is the same as writing echo 'A.txt B.txt C.txt D.cpp'
[user@work test]$ echo *
A.txt B.txt C.txt D.cpp

[user@work test]$ echo "*"
*

[user@work test]$ echo '*'
*

# The following is the same as writing echo 'A.txt B.txt C.txt'
[user@work test]$ echo *.txt
A.txt B.txt C.txt

[user@work test]$ echo "*.txt"
*.txt

[user@work test]$ echo '*.txt'
*.txt

[user@work test]$ myname=is Fred; echo $myname
bash: Fred: command not found

[user@work test]$ myname=is\ Fred; echo $myname
is Fred

[user@work test]$ myname="is Fred"; echo $myname
is Fred

[user@work test]$ myname='is Fred'; echo $myname
is Fred

따옴표가 작동하는 방식을 이해하는 것은 Bash를 이해하는 데 핵심입니다. 예를 들면 다음과 같습니다.

# for will operate on each file name separately (like an array), looping 3 times.
[user@work test]$ for f in $(echo *txt); do echo "$f"; done;
A.txt
B.txt
C.txt

# for will see only the string, 'A.txt B.txt C.txt' and loop just once.
[user@work test]$ for f in "$(echo *txt)"; do echo "$f"; done;
A.txt B.txt C.txt

# this just returns the string - it can't be evaluated in single quotes.
[user@work test]$ for f in '$(echo *txt)'; do echo "$f"; done;
$(echo *txt)

작은 따옴표를 사용하여 변수를 통해 명령을 전달할 수 있습니다. 작은 따옴표는 평가를 방해합니다. 큰 따옴표가 평가됩니다.

# This returns three distinct elements, like an array.
[user@work test]$ echo='echo *.txt'; echo $($echo)
A.txt B.txt C.txt

# This returns what looks like three elements, but it is actually a single string.
[user@work test]$ echo='echo *.txt'; echo "$($echo)"
A.txt B.txt C.txt

# This cannot be evaluated, so it returns whatever is between quotes, literally.
[user@work test]$ echo='echo *.txt'; echo '$($echo)'
$($echo)

큰 따옴표 안에 작은 따옴표를 사용할 수 있고 큰 따옴표 안에 큰 따옴표를 사용할 수 있지만 작은 따옴표 안에 큰 따옴표를 사용 하지 않아야합니다 (이스케이프하지 않고) 평가되지 않으며 문자 그대로 해석됩니다. 작은 따옴표 안의 작은 따옴표는 이스케이프하지 않고 수행해서는 안됩니다.

Bash를 효과적으로 사용하려면 따옴표를 철저히 이해해야합니다. 매우 중요!

일반적으로 Bash가 배열과 같은 요소로 무언가를 확장하려면 따옴표를 사용하지 않고 변경되지 않는 리터럴 문자열에 작은 따옴표를 사용하고 변수에 큰 따옴표를 자유롭게 사용합니다 모든 유형의 문자열을 반환 할 가능성이 높습니다. 이것은 공백과 특수 문자가 유지되도록하기위한 것입니다.


큰 따옴표 안에 큰 따옴표를 어떻게 사용 하시겠습니까 ??? 오타입니까? 왜 작은 따옴표 안에 큰 따옴표를 피해야합니까? 어쩌면 당신이 문장을 섞은 것 같아요?
바이트 사령관

@ByteCommander 그렇습니다. 큰 따옴표 안에 놓인 큰 따옴표의 개념은 꽤 일반적으로 사용됩니다 . 눈에 띄는 작업 예는 이 게시물 을 참조하십시오 . 일반적으로 경로 문자열과 관련하여 공백이 포함 된 문자열을 보호하기 위해 수행됩니다. 큰 따옴표는 이스케이프가 있거나없는 작은 따옴표 내에서 사용될 수 있지만 문자 그대로 해석되므로 평가로 이어지지 않습니다. 포스트 에서이 점을 분명히 할 것입니다.
AsymLabs
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.