Как правильно использовать (вложенные | двойные | простые) кавычки - PullRequest
1 голос
/ 11 августа 2009

Я уверен, что этот вопрос может показаться некоторым из вас глупым, но я здесь, чтобы выучить.
Верны ли эти предположения для большинства языков?
РЕДАКТИРОВАТЬ : ОК, давайте предположим, что я говорю о сценариях Perl / Bash.

'Single quotes'

=> Никакой интерпретации (например, '$' или любой метасимвол будет рассматриваться как символ и будет напечатан на экране)

"Double quotes" 

=> Переменная интерпретация

Чтобы быть более точным в моих проблемах, я пишу несколько сценариев оболочки (в которых кавычки иногда могут быть большими хлопотами) и написал следующую строку:

CODIR=`pwd | sed -e "s/$MODNAME//"`

Если бы я использовал одинарные кавычки в своем sed, мой шаблон был бы '$ MODNAME', верно? (а не фактическое значение $ MODNAME, которое в данном случае является `alpha ')

Другая проблема, с которой я столкнулся, с awk внутри эха:

USAGE=`echo -ne "\
Usage : ./\`basename $0\` [-hnvV]\n\
\`ls -l ${MODPATH}/reference/ | awk -F " " '$8 ~ /\w+/{print "> ",$8}'\`"`

Я потратил некоторое время на его отладку. Я пришел к выводу, что обратные метки были исключены, так что интерпретатор не «разделяет» команду (и останавливается прямо перед «basename»). В команде awk '$ 8' успешно интерпретируется awk, то есть не оболочкой. Что если я захочу использовать переменную оболочки? Буду ли я писать awk -F "\" $ MY_SHELL_VAR \ ""? Поскольку $ MY_SHELL_VAR как есть, будет интерпретироваться awk, не так ли?

Не стесняйтесь добавлять любую информацию о цитировании или кавычках!

Спасибо! :)

Ответы [ 8 ]

7 голосов
/ 11 августа 2009

Это сильно зависит от языка. Например, в семействе C / Java / C ++ / C # и т. Д. Вы не можете использовать одинарные кавычки для строки - они только для одиночных символов.

Я думаю, что гораздо лучше правильно выучить правила для языков, которые вам действительно интересны, чем пытаться обобщать.

4 голосов
/ 12 августа 2009

В сценариях bash обратные пометки не рекомендуются в пользу $ () отчасти потому, что неясно, как должны работать вложенные кавычки и экранирование. Вы также можете взглянуть на Bash Pitfalls .

4 голосов
/ 11 августа 2009

Верны ли эти предположения для большинства языков?

Ответ: Нет

2 голосов
/ 11 августа 2009

В Perl у вас также есть q () и qq (), чтобы помочь вам во вложенных ситуациях цитирования:

my $x = q(a string with 'single quotes');
my $y = qq(an $interpreted string with "double quotes");

Это, безусловно, поможет вам избежать "\" излишне \ "" "\" экранирования \ "внутренних кавычек.

2 голосов
/ 11 августа 2009

Это определенно не то же самое для всех языков. Например, в Python одинарные и двойные кавычки являются взаимозаменяемыми. Единственное отличие состоит в том, что вы можете включать одинарные кавычки в строку в двойных кавычках, не экранируя их и наоборот («Как дела?»).

Кроме того, есть строки в тройных кавычках, которые могут занимать несколько строк.

1 голос
/ 11 августа 2009

В perl переменные в двойных кавычках будут иметь расширенные переменные.

Если вы напишите это, например:

my $email = "foo@bar.com" ;

Perl попытается расширить @bar. Если вы use strict, вы увидите жалобу на несуществующую панель массива. Если вы этого не сделаете, вы просто увидите странное поведение.

Так что лучше написать:

my $email = 'foo@bar.com' ;

По этим причинам я советую всегда использовать одинарные кавычки для строк, если вы не знаете, что вам нужно расширение переменной.

1 голос
/ 11 августа 2009

Я не знаю про perl, но для bash вам не нужно ставить обратную косую черту.

Что касается кавычек, у меня есть (очень личный) паттерн, который я называю паттерном «пять кавычек». Помогает поместить одну кавычку в строку, заключенную в одинаковые кавычки

Например:

doublequoted="some things "'"'"quoted"'"'" and some not"
simplequoted='again '"'"'quote this'"'"' but not that'

Обратите внимание, что вы можете свободно добавлять строки с различными типами кавычек, что полезно, когда вы хотите, чтобы оболочка интерпретировала некоторые переменные, но не некоторые другие:

awk -F " " '$8 ~ /\w+/{print "> ",$8, '"$SOME_SHELL_VAR"'}'

Кроме того, я больше не использую backtick, но шаблон $(...), который более разборчив и может быть вложенным.

USAGE=$(echo -ne "
Usage : ./$(basename $0) [-hnvV]\n
$(ls -l ${MODPATH}/reference/ | awk -F " " '$8 ~ /\w+/{print "> ",$8}')")
1 голос
/ 11 августа 2009

Да, что-то вроде awk -F "\"$MY_SHELL_VAR\"" будет работать, однако в этом случае вы не сможете использовать переменные в awk, так как они будут интерпретироваться оболочкой, поэтому путь будет примерно таким (я буду использовать команда проще, чем ваша, если не возражаете :)):

awk -F " " '$8 ~ /\w+/{print "> ",$8, '$SOME_SHELL_VAR'}'

Обратите внимание, что одинарные кавычки заканчиваются и перезапускаются.

Самая сложная часть, как правило, заключается в передаче кавычки в аргументе команде. В этом случае вам необходимо завершить одинарную кавычку, добавить символ экранированной кавычки, снова начать кавычку, например:

awk '$1 ~ '\''{print}'

Обратите внимание, что одиночную кавычку нельзя экранировать внутри одинарных кавычек, поскольку "\" не будет рассматриваться как символ экранирования.

Это, вероятно, не связано напрямую с вашим вопросом, но все же полезно.

...