Яка різниця між файлом 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"не починає новий параметр, але повинен бути частиною поточного параметра. grep apple\ tree fileдав би той самий результат, тому що \говорить Баш нехтувати особливим значенням наступного персонажа і ставитися до цього буквально.


2
Це також видно із символами підстановки. Якщо ви це зробите, grep a*b equations.txtто він буде шукати a*b, якщо у поточному каталозі не буде файла, який починається з a і закінчується b, у цьому випадку (оскільки (ba) sh розширить назви файлів у командному рядку) grep буде викликаний з повні різні параметри, в результаті чого різні результати. Зазвичай це більше проблеми з find, оскільки така команда find . -name *.txtпризведе до несподіваної поведінки, якщо в поточному каталозі є файл txt. Краще в цьому випадку використовувати лапки.
SztupY

4
Ще один важливий момент - різниця між подвійними лапками ( ") та одинарними лапками ( '). Одиночні лапки перешкоджають інтерпретації певних символів, таких як $, тоді як подвійні лапки дозволяють інтерпретувати. Наприклад, grep '${USER}'буде шукати текст ${USER}, тоді як grep "${USER}"буде шукати текст, який USERмістить змінна (наприклад johnstacen).
Падді Ландау

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

Розуміння того, як працюють котирування, має вирішальне значення для розуміння Баша. Наприклад:

# 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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.