2014-09-25 3 views
0

Каков наилучший способ сделать цикл for через маску файла?bash loop over file mask

E.g. если маска не распространяется на любой файл, тогда цикл не должен запускаться; иначе он должен работать над всеми файлами, к которым он распространяется.

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

+0

_file mask_? Вы имеете в виду подстановочный шаблон? – Barmar

ответ

2

Один из способов сделать это:

for f in abc*; do if [[ -f "$f" ]]; then 
    # Do something with "$f" 
fi; done 

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

Если вы хотите сохранить каталоги, используйте -e вместо -f.

Другой способ сделать это - установить опцию оболочки nullglob (может быть недоступна для всех версий bash). С установкой nullglob шаблоны, которые не соответствуют ни одному имени файла, не приведут ни к чему, а не к неизменному.

shopt -s nullglob 
for f in abc*; do 
    # do something with $f 
done 
shopt -u nullglob 

(Это оставляет nullglob набора для продолжительности цикла for. Вы можете сбросить его внутри цикла, не дожидаясь конца, на небольшую стоимости выполнения shopt -u на каждом цикле.)

+0

Я думаю, что -f также отфильтрует символические ссылки – cnst

+0

@cnst: TIAS слишком коротка, чтобы быть комментарием. Но, во всяком случае, символические ссылки на файлы: '-f' – rici

0

Используйте опцию nullglob оболочки, чтобы сделать подстановочные, который не соответствует ничего расширить в ничто, а не возвращаться сам подстановочные:

shopt -s nullglob 
for file in abc* 
do 
    ... 
done