Powłoka Bash: wyświetla listę wszystkich plików typu .png lub .PNG?

14

Jak w skrypcie bash mogę powiedzieć „dla wszystkich plików typu .png lub .PNG”?

Próbuję :

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

ale pojawia się błąd składniowy.

Szymon
źródło

Odpowiedzi:

18

Jeśli chcesz wszystkie możliwe kombinacje, użyj:

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

lub

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

chociaż spowoduje to, że wszystkie globusy powłoki skryptu (tzn. dopasowania plików symboli wieloznacznych) nie będą rozróżniać wielkości liter do momentu uruchomienia shopt -u nocaseglob.

Jeśli naprawdę chcesz tylko .PNG i .png (a nie na przykład .PnG lub .pnG), użyj albo

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

lub

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

... powodem sprawdzenia nullglob lub istnienia jest to, że jeśli masz tylko małe lub tylko wielkie litery rozszerzenia, spowoduje to umieszczenie niedopasowanego wzorca na liście plików, co prowadzi do błędu w treści pętli. Podobnie jak w przypadku nocaseglob, możesz chcieć później wyłączyć opcję powłoki nullglob (chociaż z mojego doświadczenia włączenie nullglob jest często dobre, szczególnie w skrypcie). Właściwie uważam, że dobrym pomysłem jest użycie sprawdzania nocaseglob lub sprawdzania istnienia dla wszystkich takich dopasowań plików, na wypadek, gdyby nie było żadnych dopasowań.

Gordon Davisson
źródło
5
for i in *.{png,PNG}
glenn jackman
@glenn: To też by działało (odpowiednik `* .png * .PNG), chociaż nadal potrzebujesz nullglob lub sprawdzania istnienia.
Gordon Davisson
5

Możesz także wypróbować jedną linijkę, taką jak

odnaleźć . -iname "* .png" -exec ....

lub

odnaleźć . -iname "* .png" | xargs ....

Edytuj
Zobacz także komentarz @ Yab poniżej dotyczący rekurencji.

Alain Pannetier
źródło
1
find jest jednak domyślnie rekurencyjny, więc aby uzyskać ten sam wynik, zadaje pytanie, musisz zrobić find -maxdepth 1 -iname "*.png"
Yab
@Yab, masz całkowitą rację. Przeoczyłem ten aspekt.
Alain Pannetier
1

ls jest tu prawie bezużyteczne, ale dla przypomnienia tutaj składnia jest bliżej twojej próby:

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

Uwagi:

  • Zakładam, że chcesz mieć zarówno wielkie, jak i małe zdjęcia. Separator && oznacza przetwarzanie plików png tylko wtedy, gdy istnieją pliki PNG, co prawdopodobnie nie ma większego sensu.
  • wyświetli się komunikat o błędzie, jeśli nie zostaną znalezione żadne pliki z żadnym wzorcem.
jlliagre
źródło