Оболочка Bash: список всех файлов типа .png или .PNG?


14

В скрипте bash, как я могу сказать «для всех файлов типа .png или .PNG»?

Я стараюсь :

for i in (`ls *.PNG` && `ls *.png`)

но получаю синтаксическую ошибку.

Ответы:


18

Если вы хотите все возможные комбинации, используйте:

for i in *.[Pp][Nn][Gg]; do

или

shopt -s nocaseglob
for i in *.png; do

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

Если вы действительно хотите просто .PNG и .png (а не, например, .PnG или .pnG), используйте либо

shopt -s nullglob
for i in *.png *.PNG; do

или

for i in *.png *.PNG; do
    [[ -e "$i" ]] || continue

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


5
for i in *.{png,PNG}
Гленн Джекман

@glenn: Это тоже сработало бы (эквивалентно `* .png * .PNG), хотя вам все еще нужен nullglob или проверка существования.
Гордон Дэвиссон

5

Вы также можете попробовать некоторые однострочные, такие как

находить . -имя "* .png" -exec ....

или

находить . -имя "* .png" | xargs ....

Редактировать
Смотрите также комментарий @ Yab ниже о рекурсии.


1
Однако по умолчанию поиск является рекурсивным, поэтому, чтобы получить тот же результат, который задает вопрос, вам придется это сделать find -maxdepth 1 -iname "*.png"
Яб

@ Яб, ты совершенно прав. Я упустил из виду этот аспект.
Ален Паннетье

1

ls здесь почти бесполезен, но для записи вот синтаксис, более близкий к вашей попытке:

for i in $(ls *.PNG ; ls *.png)

Примечания:

  • Я предполагаю, что вы хотите и заглавные и строчные картинки. Разделитель && будет означать обработку файлов PNG, только если существуют файлы PNG, что, вероятно, не имеет особого смысла.
  • у вас будут отображаться сообщения об ошибках, если ни один из файлов не найден.
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.