Możesz użyć globstar.
Po włączeniu globstaropcji powłoki wszystko czego potrzebujesz to gzip -vk **/*.{css,html}.
Powłoka Bash ma globstaropcję, która pozwala pisać rekurencyjnych globs z **. shopt -s globstarumożliwia to. Ale możesz nie chcieć tego robić w przypadku innych poleceń uruchamianych później, aby zamiast tego można było uruchomić je i gzip polecenie w podpowłoce .
To polecenie gzips wszystkich .cssi .htmlplików w bieżącym katalogu dowolnego z jego podkatalogów, dowolnego z ich podkatalogów itp., Zachowując oryginalne pliki ( -k) i informując o tym, co robi ( -v):
(shopt -s globstar; gzip -vk **/*.{css,html})
Jeśli chcesz dopasować nazwy plików bez rozróżniania wielkości liter, aby te rozszerzenia z niektórymi lub wszystkimi literami były włączone, możesz również włączyć nocaseglobopcję powłoki:
(shopt -s globstar nocaseglob; gzip -vk **/*.{css,html})
;rozdziela dwa polecenia, a zewnętrzny ( )powoduje, że są one uruchamiane w podpowłoce. Ustawienie opcji powłoki w podpowłoce nie powoduje ustawienia jej w powłoce wywołującej. Jeśli nie chcesz, aby umożliwić globstarnastępnie można uruchomić shopt -s globstar; możesz po prostu uruchomić polecenie:
gzip -vk **/*.{css,html}
Możesz wyłączyć za globstarpomocą shopt -u globstar. Możesz sprawdzić, czy jest on obecnie włączony za pomocą shopt globstar.
Jak to działa
Kluczem do działania tego gzippolecenia jest to, że powłoka wykonuje na nim rozszerzenia, aby utworzyć listę każdego pliku w hierarchii katalogów o pasującej nazwie, a następnie przekazuje każdą z tych nazw plików jako argumenty gzip.
- Ekspansja nawiasów zamienia się
**/*.{css,html}w **/*.css **/*.html.
- Następnie globbing rozszerza te dwa wzorce na nazwy plików dostępnych w bieżącym katalogu (z
**powodu globstar), których nazwy plików składają się ze wszystkiego ( *), po którym następuje określony sufiks ( .csslub .htmlw tym przypadku).
To nie pasuje do plików, których nazwy zaczynają się od,. ani tych, które znajdują się w katalogach o takich nazwach. Prawdopodobnie nie masz takich plików HTML i CSS, a jeśli tak, prawdopodobnie nie chcesz ich dołączać. Ale jeśli chcesz je dołączyć, możesz je jednoznacznie dopasować w zależności od potrzeb. Na przykład zmiana **/*.{css,html}na **/{,.}*.{css,html}obejmuje pliki, które zaczynają się od, .ale nadal nie wyszukują w folderach, które to robią.
Jeśli chcesz uwzględnić zarówno pliki, których nazwy zaczynają się od, jak .i pliki w katalogach, których nazwy zaczynają się .od, to jest prostszy i prostszy sposób: włącz dotglobopcję powłoki.
(shopt -s globstar dotglob; gzip -vk **/*.{css,html})
Lub jeśli chcesz rozróżniać małe i wielkie litery oraz nazwy plików rozpoczynające się od .:
(shopt -s globstar nocaseglob dotglob; gzip -vk **/*.{css,html})
Możliwe jest, choć bardzo rzadkie, **rozwinięcie się w coś zbyt długiego.
Jeśli masz ogromną liczbę plików nazwanych w ten sposób, to może zakończyć się niepowodzeniem z komunikatem o błędzie, wyjaśniając, że powłoka nie można zbudować z wiersza poleceń, ponieważ byłoby to zbyt długo. (Nawet w przypadku tysięcy plików zwykle nie stanowi to problemu).
gzip nie zostanie w ogóle wezwany, więc nie dostaniesz w połowie wykonanej pracy.
Jeśli wystąpi ten błąd lub martwisz się nim, możesz użyć findgo -exec, tak jak opisuje steeldriver (z {} \;) lub jak opisuję poniżej (z {} +).
Możesz używać findz -execakcją i +dla wydajności.
Te gzippodpory polecenia są podane nazwy wielu plików mają być kompresowane. Ale to findpolecenie, chociaż działa dobrze i nie będzie wolne, chyba że masz wiele plików, uruchamia gzippolecenie raz dla każdego pliku:
find . \( -name \*.css -o -name \*.html \) -exec gzip -vk {} \;
To działa i na pewno możesz go użyć. ( .wyszukuje z bieżącego katalogu. Poza tym jest to naprawdę nieco inny sposób pisania polecenia w bardzo dobrej odpowiedzi steeldriver ; możesz użyć dowolnego stylu).
Możesz także findprzekazać wiele nazw plików gzipi uruchomić go tyle razy, ile to konieczne - co prawie zawsze jest tylko raz. Aby to zrobić, użyj +zamiast\; . +Argument powinien przyjść tuż po {}. findzastępuje +dodatkowymi nazwami plików, jeśli istnieją.
find . \( -name \*.css -o -name \*.html \) -exec gzip -vk {} +
Można z niego korzystać, +nawet jeśli jest tylko kilka pasujących plików, a gdy jest ich wiele, może być zauważalnie szybsze niż oddzielne gzipwywołanie dla każdego pliku.
Jak steeldriver wspomina , można użyć -inamezamiast -namedopasować pliki, których nazwa koniec jak .cssalbo .htmlale o różnej kapitalizacji. Odpowiada to włączeniu nocaseglobw globstarmetodzie opisanej powyżej.
Wreszcie prawdopodobnie nie masz żadnych pasujących plików lub katalogów, które zaczynają się od .. Ale jeśli to zrobisz, findautomatycznie je uwzględni. Jeśli chcesz je wykluczyć (jak to się dzieje w przypadku globstarmetody opartej na szczegółach powyżej, gdy dotglobjest wyłączona), możesz :
find . -not -path '*/.*' \( -name \*.css -o -name \*.html \) -exec gzip -vk {} +
globstar-Na sposób opisany powyżej jest prostsze pisać, zwłaszcza jeśli jesteś z wyłączeniem katalogów i plików, które zaczynają się ., ponieważ jest to ustawienie domyślne.
Czego nie robić ...
Nazwy plików mogą zawierać dowolny znak oprócz separatora ścieżki /i znaku zerowego . Istnieje wiele technik, które łamią się na dziwnych nazwach plików i są zwykle bardziej skomplikowane niż techniki, które zawsze działają. Sugeruję więc unikanie ich, nawet jeśli wiesz (lub wydaje ci się, że wiesz), że są w porządku w twojej konkretnej sytuacji. I oczywiście, że należy nie używać ich, czy może masz nazwy plików ze znakami, które mogą być traktowane specjalnie, łącznie ze spacjami.
Możliwe jest bezpieczne przesyłanie danych wyjściowych finddo innego polecenia, które je przetwarza, jeśli użyjesz -print0lub podobnej akcji, aby spowodować umieszczenie znaku pustego między ścieżkami zamiast nowej linii , a nie inaczej. Nazwy plików mogą zawierać znaki nowej linii (choć zniechęcam cię do celowego nazywania ich plikami). findKomenda z -printakcji - w tym polecenia find bez wyraźnego działania, ponieważ wtedy -printjest domyślna - nie powoduje wyjście, które można bezpiecznie doprowadzanej rurami lub inaczej dostarczane do innego polecenia, które wykonuje czynność na plikach.
Dane wyjściowe findtworzone za pomocą -print0akcji mogą być bezpiecznie przesyłane do potoku xargs -0( -0flaga informuje, xargsże należy oczekiwać danych wejściowych oddzielonych od wartości zerowej).
-rdziała zgodnie z przeznaczeniem. Z man gzip : Rekurencyjnie przeglądaj strukturę katalogów. Jeśli którakolwiek z nazw plików określonych w wierszu poleceń to katalogi , gzip zejdzie do katalogu i skompresuje wszystkie znalezione tam pliki (lub rozpakuje je w przypadku gunzip). (moje podkreślenie)