Использование обратной косой черты в различных командах

С оболочкой, которая поддерживает расширенные глобусы и пустые глобусы, например zsh :

for d in ./**/rules/
do
set -- ${d}*.pdf(N)                               
(( $# > 0 )) && printf %s\\n $@
done

или bash :

shopt -s globstar
shopt -s nullglob
for d in ./**/rules/
do
set -- "${d}"*.pdf
(( $# > 0 )) && printf %s\\n "$@"
done

замените printf% s \\ n на rm , если вас устраивает результат.


Поскольку вы используете gnu / linux, вы также можете запустить:

find . -type f -regextype posix-basic -regex '.*/rules/[^/]*.pdf' -delete

remove -delete , если вы хотите выполнить пробный запуск.

4
22.02.2017, 01:44
4 ответа

Обратная косая черта часто используется, чтобы сказать «сделать следующий символ сам по себе, вместо того, чтобы придавать ему особое значение». Мы говорим, что обратная косая черта помещает в кавычки следующий символ. Это значение присутствует во многих языках программирования, включая синтаксис оболочки. Например, в rpm-qa rpmname \ * обратная косая черта вызывает передачу символа * в аргументе команды rpm-qa . Напротив, rpm-qa rpmname * заменит rpmname * списком имен файлов в текущем каталоге, начиная с rpmname .(Если подходящего файла нет, то bash оставляет только rpmname * ; по умолчанию zsh будет жаловаться на отсутствие совпадений.)

Оболочка предлагает другой способ интерпретировать символ буквально, т. Е. Сделать его стоять за себя, а не интерпретироваться каким-то особым образом. Это цитирование, отменяющее особое значение целой последовательности символов. Есть два вида цитат:одинарные кавычки ' заставляют каждый символ стоять сам за себя до следующей одинарной кавычки, тогда как двойные кавычки « сохраняют особое значение для нескольких символов (» , ] $ , \ и `). В echo 'that' \ '' s no moon ' команда echo принимает единственный аргумент, который представляет собой конкатенацию , что (записанное с буквальным строка, а не то, что в этом конкретном случае был какой-либо символ со специальным значением), ' (одинарная кавычка с обратной косой чертой отменяет особое значение этой одинарной кавычки, поэтому она заменяется одним символом одинарной кавычки), и s no moon (пробелы теряют свое особое значение, поскольку они заключены в кавычки: вместо разделения аргументов они являются частью аргумента).

В оболочке, когда обратная косая черта имеет особое значение, это обычно заключается в заключении следующего символа в кавычки. Но:

  • Внутри одинарных кавычек обратная косая черта не имеет особого значения.
  • Внутри двойных кавычек обратная косая черта помещает в кавычки следующий символ, только если он один из "$ \` . В противном случае и обратная косая черта, и следующий символ интерпретируются буквально, например, "\ a" представляет собой двухсимвольную строку \ a .
  • Внутри литералов с одинарными кавычками в виде доллара обратная косая черта имеет другое значение, аналогичное значению в C . Обратная косая черта с последующим восьмеричным цифрами или определенными буквами предоставляет альтернативные способы ввода символов, что полезно для непечатаемых символов.Например, \ n - это N в нижнем регистре, «\ n» - это обратная косая черта + n, но $ '\ n' - это символ новой строки.

В grep '\ s / tmp' / etc / fstab одинарные кавычки приводят к тому, что grep получает аргумент \ s / tmp . Этот аргумент является регулярным выражением . Существует множество вариантов синтаксиса для регулярных выражений, но большинство из них основано на одном из двух стандартов: Базовые регулярные выражения POSIX (BRE) и расширенные регулярные выражения (ERE) . ERE следуют широко распространенному соглашению, согласно которому обратная косая черта, за которой следует что-либо, кроме буквы или цифры, помещает следующий символ в кавычки. Но по историческим причинам в BRE обратная косая черта иногда может сделать следующий символ особенным, хотя иначе это было бы не так. В этом случае \ s - это расширение GNU grep для базового синтаксиса регулярных выражений, доступное как с BRE, так и с ERE, что означает один пробельный символ. Таким образом, grep '\ s / tmp' / etc / fstab перечисляет строки в / etc / fstab , содержащие / tmp , которым предшествует пробел или табуляция.

3
27.01.2020, 20:53

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

# echo 'It\'s a string!'

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

Другой случай - противоположный, когда вам нужен «нормальный» символ, чтобы иметь какое-то особое значение:

# grep '\s/tmp' /etc/fstab

В приведенном выше примере обратная косая черта указывает grep, что s имеет особое значение и не является буквальным s (это пробел RegEx: пробел, табуляция, новая строка, возврат каретки, вертикальная табуляция)

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

Изменить:

Для вашего первого примера:

rpm-qa rpmname\*

Здесь * имеет особое значение (все, что начинается с 'rpmname'), но чтобы оболочка не пыталась его расширить, вы избегаете его, поэтому команда rpm получает литерал * и может обрабатывать его соответствующим образом.

Это происходит столько раз, сколько строк будет интерпретироваться, и может возникнуть настоящая проблема, когда строка передается несколькими командами.

1
27.01.2020, 20:53

Я предполагаю, что вы используете bash или что-то в этом роде.

Прежде всего вы должны понять, как bash оценивает ваш ввод. В bash можно использовать множество специальных символов. Некоторые из них, например, *; ~ $

Когда вы вводите свой ввод, bash попытается заменить все символы, которые должны быть. Например, переменные, начинающиеся со знака $ . * будет заменен каждым файлом / каталогом, который присутствует в каталоге, в котором вы сейчас находитесь (определите его с помощью pwd ).

Если шаг замены выполнен, bash, наконец, выполнит (с помощью fork () ) указанную вами программу.

\ указывает bash игнорировать данный специальный символ: \ *

1
27.01.2020, 20:53

\ используется как для экранирования специальных символов, так и для запуска регулярных выражений.

Ваша команда rpm экранирует * , что в данном случае функционально аналогично отсутствию экранирования. RPM знает, что * является недопустимым символом пакета, поэтому он интерпретирует его, даже если вы его экранируете. Экранирование специального символа чаще используется в таких ситуациях, как обработка имен файлов с использованием не буквенно-цифровых символов.

Предположим, что у нас два файла, один с именем «foo-biz-bar», а другой «foo * bar», и мы хотим видеть только «foo * bar». Первый результат ниже возникает из-за того, что неэкранированный * является подстановочным знаком большого двоичного объекта.

$ ls foo*bar
foo*bar foo-biz-bar
$ ls foo\*bar
foo*baz

\ s в примере grep - это регулярное выражение, означающее «любые пробелы», то есть табуляции и пробелы.

Дополнительная литература

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

Мне очень помогла книга «Оболочки Unix на примерах». Также было рассмотрено обширное использование sed , grep и awk .

1
27.01.2020, 20:53

Теги

Похожие вопросы