ZSH - Зацикливать файлы, игнорировать определенные шаблоны (no ls или find)

Вы можете использовать следующую команду для очистки всех необязательных и дополнительных пакетов: sudo apt-get --simulate purge $(dpkg-query -Wf '${Package;-40}${Priority}\n' | awk '$2 ~ /optional|extra/ { print $1 }')

Флаг --simulate позволяет вам увидеть, что будет удалено, без фактического удаления всего. Снимите этот флаг, чтобы действительно удалить пакеты.

Вам придется переустановить git, так как он будет удален вместе с другими дополнительными и опциональными пакетами.

Вам могут понадобиться некоторые необязательные и дополнительные пакеты, поэтому удаляйте их с осторожностью. Подробнее здесь: https://askubuntu.com/questions/79665/keep-only-essential-packages

1
06.03.2019, 15:13
1 ответ

Zsh предоставляет очень удобные способы перечисления файлов. Они задокументированы в руководстве «Генерация имени файла» , но следовать руководству по zsh не очень легко.

По умолчанию, если нет подходящих файлов, вы получите сообщение об ошибке, что часто желательно в командной строке, но не в сценариях. Чтобы отключить эту ошибку, либо поместите это в начало вашего скрипта, чтобы включить опциюnull_glob:

setopt null_glob
…
for x in *; do …

или используйте квалификаторNglob:

# Reliably iterate over non-dot files
for x in *(N); do …

Любой из приведенных выше фрагментов перебирает все файлы в текущем каталоге, которые не являются точечными файлами . Если такого файла нет, цикл вообще не запускается (, в отличие от sh, где тело цикла бесполезно запускается один раз на нераскрытом глобусе *, и по умолчанию zsh, где глобус вызывает ошибку ).

Чтобы включить точечные файлы в итерацию, либо включите параметрgot_glob, либо используйте квалификатор Dglob.

# Reliably iterate over all files in the current directory
for x in *(DN); do …

Я рекомендую метод квалификатора glob, даже если он более подробный, потому что он будет вести себя так же, даже если вы скопируете -вставку этого фрагмента в скрипт, который не включает те же параметры.

Чтобы исключить определенные файлы на основе их имени, вы можете использовать операторы glob^и ~. Обратите внимание, что для этого требуется setopt extended_globв вашем скрипте² (, это не унаследовано от вашей среды выполнения или вашего .zshrc¹ ). Например, чтобы исключить файлы *.jpg, напишите либо *~*.jpg, либо ^*.jpg.

(Обратите внимание, то, что вы написали, *^.jpg, по умолчанию вызовет ошибку в zsh. Если вы видите напечатанное *^.jpg, то либо вы используете zsh с выключенным nomatch, (он включен по умолчанию ), что обычно делается только при эмуляции sh или ksh, либо вы на самом деле этот скрипт запускается под оболочкой sh, вероятно, потому, что в нем отсутствует строка shebang вверху.)

setopt extended_glob
# Iterate over all the files in the current directory except *.jpg and.*
for x in *~*.jpg(N); do …

Если вы хотите рекурсивно перемещаться по подкаталогам,это просто :просто используйте**/.

setopt extended_glob
# Iterate over all the files in the current directory and its (grand-)*children except *.jpg and.*
for x in **/*~*.jpg(N); do …

С помощью квалификаторов glob вы также можете выбирать файлы на основе условий, отличных от их имени. Например, чтобы перебирать только обычные файлы, исключая каталоги, символические ссылки и т. д.:

# Iterate over all regular files in the current directory and its (grand-)*children except *.jpg and.*
for x in **/*(.DN); do …

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

¹ Вы можете поместить setopt extended_globв ~/.zshenv, но я настоятельно не рекомендую использовать .zshenv, потому что любой сценарий, который делает предположения о том, что там находится, сломается на другом компьютере или другой учетной записи.
² Если вы пишете функцию завершения zsh, она запускается в среде, где включен extended_glob.

10
27.01.2020, 23:18

Теги

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