С оболочкой, которая поддерживает расширенные глобусы и пустые глобусы, например 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
, если вы хотите выполнить пробный запуск.
Обратная косая черта часто используется, чтобы сказать «сделать следующий символ сам по себе, вместо того, чтобы придавать ему особое значение». Мы говорим, что обратная косая черта помещает в кавычки следующий символ. Это значение присутствует во многих языках программирования, включая синтаксис оболочки. Например, в rpm-qa rpmname \ *
обратная косая черта вызывает передачу символа *
в аргументе команды rpm-qa
. Напротив, rpm-qa rpmname *
заменит rpmname *
списком имен файлов в текущем каталоге, начиная с rpmname
.(Если подходящего файла нет, то bash оставляет только rpmname *
; по умолчанию zsh будет жаловаться на отсутствие совпадений.)
Оболочка предлагает другой способ интерпретировать символ буквально, т. Е. Сделать его стоять за себя, а не интерпретироваться каким-то особым образом. Это цитирование, отменяющее особое значение целой последовательности символов. Есть два вида цитат:одинарные кавычки '
заставляют каждый символ стоять сам за себя до следующей одинарной кавычки, тогда как двойные кавычки «
сохраняют особое значение для нескольких символов (»
, ] $
, \
и `
). В echo 'that' \ '' s no moon '
команда echo
принимает единственный аргумент, который представляет собой конкатенацию , что
(записанное с буквальным строка, а не то, что в этом конкретном случае был какой-либо символ со специальным значением), '
(одинарная кавычка с обратной косой чертой отменяет особое значение этой одинарной кавычки, поэтому она заменяется одним символом одинарной кавычки), и s no moon
(пробелы теряют свое особое значение, поскольку они заключены в кавычки: вместо разделения аргументов они являются частью аргумента).
В оболочке, когда обратная косая черта имеет особое значение, это обычно заключается в заключении следующего символа в кавычки. Но:
"$ \`
. В противном случае и обратная косая черта, и следующий символ интерпретируются буквально, например, "\ a"
представляет собой двухсимвольную строку \ a
. \ 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
, которым предшествует пробел или табуляция.
Вы правы, существует общепринятое соглашение, согласно которому обратная косая черта используется для экранирования символов, либо указанный символ имеет особое значение, и вы хотите, чтобы он был буквальным:
# echo 'It\'s a string!'
В приведенном выше примере апостроф используется для ограничения буквальной строки, но, поскольку вам нужен апостроф внутри строки, вы должны его избежать.
Другой случай - противоположный, когда вам нужен «нормальный» символ, чтобы иметь какое-то особое значение:
# grep '\s/tmp' /etc/fstab
В приведенном выше примере обратная косая черта указывает grep, что s
имеет особое значение и не является буквальным s
(это пробел RegEx: пробел, табуляция, новая строка, возврат каретки, вертикальная табуляция)
Другими словами, когда у символа есть 2 возможных значения, вы избегаете его, чтобы быть второстепенным значением.
Изменить:
Для вашего первого примера:
rpm-qa rpmname\*
Здесь *
имеет особое значение (все, что начинается с 'rpmname'), но чтобы оболочка не пыталась его расширить, вы избегаете его, поэтому команда rpm
получает литерал *
и может обрабатывать его соответствующим образом.
Это происходит столько раз, сколько строк будет интерпретироваться, и может возникнуть настоящая проблема, когда строка передается несколькими командами.
Я предполагаю, что вы используете bash или что-то в этом роде.
Прежде всего вы должны понять, как bash оценивает ваш ввод.
В bash можно использовать множество специальных символов. Некоторые из них, например, *; ~ $
Когда вы вводите свой ввод, bash попытается заменить все символы, которые должны быть. Например, переменные, начинающиеся со знака $
. *
будет заменен каждым файлом / каталогом, который присутствует в каталоге, в котором вы сейчас находитесь (определите его с помощью pwd
).
Если шаг замены выполнен, bash, наконец, выполнит (с помощью fork ()
) указанную вами программу.
\
указывает bash игнорировать данный специальный символ: \ *
\
используется как для экранирования специальных символов, так и для запуска регулярных выражений.
Ваша команда 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
.