2010-05-26 2 views
28

Часто бывает, что я хочу выполнить команду для всех файлов (включая скрытые файлы) в каталоге. При попытке использованияКак использовать шаблон. * В bash, но исключить родительский каталог (..)?

chmod g+w * .* 

она изменяет права доступа на все файлы, которые я хочу (в каталоге) и все файлы в родительском каталоге (что я хочу оставить в покое).

Есть ли подстановочный знак, который делает правильные вещи или мне нужно, чтобы начать поиск?

ответ

37

Вам понадобятся два шаблона глобуса для покрытия всех потенциальных «точечных файлов»: .[^.]* и ..?*.

Первый соответствует всем позициям в каталоге с двумя или более символами, где первый символ является точкой, а второй символ не является точкой. Второе записывает записи с тремя или более символами, начинающимися с .. (это исключает .., поскольку оно имеет только два символа и начинается с ., но включает (маловероятные) записи, такие как ..foo).

chmod g+w .[^.]* ..?* 

Это должно хорошо работать в большинстве оболочек и подходит для сценариев.


Для регулярного интерактивного использования шаблоны могут быть слишком сложными для запоминания. В этих случаях у вашей оболочки может быть более удобный способ пропустить . и ... zsh всегда исключает . и .. из таких моделей, как .*. С bash вы должны использовать переменную оболочки GLOBIGNORE.

# bash 
GLOBIGNORE=.:.. 
echo .* 

Вы могли бы рассмотреть вопрос о создании GLOBIGNORE в одном из ваших Баш файлов настройки (например, .bash_profile/.bash_login или .bashrc). Остерегайтесь, однако, привыкнуть к этой настройке, если вы часто используете другие среды. Если вы запустили команду chmod g+w .* в среде, в которой отсутствует ваша настройка, вы неожиданно закончите, включая . и .. в своей команде.

Кроме того, вы можете настроить оболочки для включения «точечных файлов» в шаблоны, которые не начинаются с явной точки (например, *).

# zsh 
setopt glob_dots 

# bash 
shopt -s dotglob 


# show all files, even “dot files” 
echo * 
+5

Собственно, что GLOBIGNORE - хороший. Вы можете сделать это временно с помощью '(GLOBIGNORE = ..; echo. *)', Если вы не хотите делать его постоянным. +1 для этой маленькой части информации. – paxdiablo

+5

Существует оговорка с «. [^.] * ..? * 'Glob, где он обычно будет жаловаться на несоответствие части ...? *, Если вы не будете покупать nullglob. – pixelbeat

2

Обычно я просто использовал . .[a-zA-Z0-9]*, так как мои имена файлов, как правило, следуют определенным правилам, но это не поймает все возможных случаев.

Вы можете Использование:

chmod g+w $(ls -1a | grep -v '^..$') 

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

Конечно, если вы просто хотите сделать файлы, вы можете использовать:

find . -maxdepth 0 -type f -exec chmod g+w {} ';' 

или, еще одно решение, которое должно делать все файлы и каталоги, кроме .. один:

for i in * .* ; do if [[ ${i} != ".." ]] ; then chmod g+w "$i"; fi done 

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

+0

просто удалить Grep -v «^ $.», Так как Allan хочет скрытые файлы, но не родительскую папку –

1

Поскольку вы не можете установить dotglob для остальной части вашей Баш сессии вы можете установить его для одного набора команд, запустив в подпроцесс, как так:

$ (shopt -s dotglob; chmod g+w ./*) 
2

Что я сделал

tar --directory my_directory --file my_directory.tar --create `ls -A mydirectory/` 

Работает нормально ls -A my_directory расширяется до всего каталога, кроме . и ... Нет странных глобусов, и на одной линии.

ps: Возможно, кто-то скажет мне, почему это не очень хорошая идея. : Р

+0

да, он отлично работает (опция «Почти все» в ls, однако для этого вы начинаете другой процесс, в данном случае/bin/ls .. обычно не плохая идея, однако, если вы работаете с 10 000 +, он может немного укусить немного ресурсов - globbing выполняется оболочкой и не запускает какие-либо процессы, чтобы составить список, и действительно большинство людей могут уйти с помощью *. [^. ] *, который в основном похож на лысого человека с моноклем, поэтому его было легко запомнить (плюс его довольно симпатичное регулярное выражение, не все знают регулярное выражение), или я вне линии здесь> :) – osirisgothra

+1

Это не удается если имена файлов содержат пробелы. –

0

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

chmod g+w * ...*