editphpini() subl /usr/local/etc/php/${1[1]}.${1[2,-1]}/php.ini
${1[1]}.${1[2,-1]}
- это один из многих способов преобразования xyz
в x.yz
. Другими подходами могут быть: ${1[1]}.${1#?}
, или ${1/(#m)?/$MATCH.}
, или ${(j:.:)${(s::)1}}
(для x.y.z
)
Во-первых, extglob управляет тем, что ls
видит в своей командной строке. Он не контролирует то, что ls
делает с тем, что он видит в командной строке. Это важно, потому что опция -R
для ls
указывает ls
рекурсивно исследовать любые каталоги, которые он видит в командной строке. Таким образом, даже если каталоги * uploads *
явно не указаны в командной строке, ls
найдет их, когда исследует их родительские каталоги.
Во-вторых, как вы знаете, не разбирает ls . Вывод ls
не предназначен для использования в конвейерах или скриптах. Попытки использовать это в конечном итоге приводят к несчастью.
В-третьих, чтобы получить нужные файлы, попробуйте:
find ./public_html ! -path '*uploads*'
Чтобы объяснить:
./ public_html
сообщает find начать поиск в ./ public_html
каталог.
Сама по себе опция -path '* uploads *'
соответствует любому пути, содержащему шаблон * uploads *
. ( -path
аналогичен параметру find -name
, но путь
включает имена каталогов.) Предыдущий !
, однако, указывает на отрицание. Итак, вариант ! -path '* uploads *'
исключает любое соответствие пути * uploads *
.
Чтобы получить вывод в стиле ls
при использовании функций find
, рассмотрите:
find ./public_html ! -path '*uploads*' -exec ls -dalh {} +
John1024 добавил хорошее решение вашей очевидной проблемы, но, судя по комментариям, вы хотели бы лучше понять extglob. Я подозреваю, что одно из основных недоразумений могло заключаться в том, что extglobs будут работать рекурсивно - что высказывание ./ public_html /! (* Uploads *)
исключает что-то с именем ./ public_html / wp-content / uploads /
. Globs (расширение имени файла) одновременно работает только на уровне одного каталога. Похоронен в руководстве по bash в разделе Расширение имени файла :
При сопоставлении имени файла символ косой черты всегда должен совпадать явно.
Итак, как сказал Джон1024, команда ls
не имела никаких (расширенных) параметров, которые имели бы форму ./ public_html / * uploads *
, но она могла имели такой параметр, как ./ public_html / wp-content
(который не соответствует исключенному шаблону), который затем было сказано -R
для рекурсивного перечисления.
Чтобы исключить каталоги * uploads *
с помощью extglobs в командной строке, вам нужно будет создать команду с таким количеством исключений, сколько имеется подкаталогов:
ls -dalh ./public_html/!(*uploads*) \
./public_html/!(*uploads*)/!(*uploads*) \
./public_html/!(*uploads*)/!(*uploads*)/!(*uploads*)
# ... etc ...
... также будьте осторожны, чтобы не использовать флаг ls -R
. Тот же риск -R
будет применяться к команде chmod. Потенциальный риск здесь состоит в том, что если в каком-либо подкаталоге «слишком много» файлов, вы рискуете заполнить список аргументов для ls
. Этот подход хрупок, поскольку он не будет обнаруживать вновь созданные каталоги, глубина которых превышает количество написанных вами шаблонов, и сломает ( ls
будет жаловаться на отсутствие каталога), если вы когда-нибудь имело на меньше подкаталогов , чем количество заданных шаблонов, что является длинным объяснением того, почему find является правильным инструментом для этой работы.