Когда использовать одинарные кавычки, двойные кавычки в grep?

20

При поиске простого шаблона «привет» в файле работают все следующие формы grep:

  • grep hello file1
  • grep 'привет' file1
  • grep "привет" file1

Есть ли конкретный случай, когда одна из вышеперечисленных форм работает, а другие нет. Имеет ли какое-то значение, если я использую одно вместо другого?


источник

Ответы:

25

Это на самом деле зависит от вашей оболочки. Кавычки (любого рода) предназначены прежде всего для работы с пробелами. Например, следующее:

grep hello world file1

будет искать слово "привет" в файлах "мир" и "файл1", а

grep "hello world" file1

будет искать "привет мир" в file1.

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

VAR="serverfault"
grep '$VAR' file1
grep "$VAR" file1

Первый grepбудет искать буквальную строку «$ VAR1» в file1. Вторая развернет переменную «$ VAR» и будет искать строку «serverfault» в file1.

Джеймс Снерингер
источник
Ключевым моментом, который стоит отметить, является то, что в исходном вопросе grep фактически каждый раз получает одни и те же аргументы.
MikeyB
2
Будь осторожен там. $является концом строки в регулярном выражении, поэтому $VAR1никогда не должно совпадать. Это работает с GNU grep, но я бы не стал рассчитывать на такое поведение. Вы должны были \$VAR1бы безопасно соответствовать буквальной строке. (И вам понадобятся дополнительные обратные слеши, если они в двойных кавычках.)
Стивен Притчард
7

Джеймс прав, но, добавив еще несколько данных, я думаю, что лучший способ думать об этом - это аргументы команды: вы намерены «привет» и «мир», чтобы быть двумя аргументами, или «привет мир», чтобы быть одним аргумент.

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

Также важно отметить, что в некоторых случаях вам нужно использовать оба типа кавычек в одном аргументе. Помните, что (по умолчанию) аргументы разделяются пробелами, поэтому, если вы не оставляете пробел, вы все равно указываете тот же аргумент.

Механизм одинарных кавычек большинства оболочек не допускает никаких специальных символов, а это означает, что любой экземпляр другой одинарной кавычки, даже если она кажется экранированной, завершает кавычку. Поэтому невозможно передать строку с одинарной кавычкой внутри одинарной кавычки, и вы должны использовать двойные кавычки. Это может быть больно, когда вы хотите передать аргумент, который содержит одинарные кавычки и что-то, что будет интерпретировано, но вы не хотите, чтобы это было. Например, если вы хотите передать буквальную строку «$ VAR - это переменная», вы должны сделать это следующим образом:

"'"'$VAR'"' is a variable"

На самом деле это конкатенация трех кавычек:

"'"
'$VAR'
"' is a variable"

или с удаленными кавычками:

'
$VAR
' is a variable

На самом деле, с большинством оболочек, вы также можете сделать это следующим образом:

"'\$VAR' is a variable"

где обратная косая черта (" \") говорит оболочке принять буквально следующий символ и не делать никаких расширений.

Но есть некоторые случаи, когда вам приходится делать это путем объединения нескольких строк, а не то, чтобы я мог привести пример прямо сейчас.

wfaulk
источник