gzip все файлы с определенными расширениями

Я пытаюсь сжать все файлы в Ubuntu, которые имеют расширение .css, .html или .js. в верхнем каталоге и всех подкаталогах. Я хочу сохранить исходные файлы и перезаписать файл .gz, если он уже существует.

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

Я пытался запустить скрипт, который выглядит следующим образом:

gzip -rkf *.css
gzip -rkf *.html
... one line for each file extension

Во-первых: мне нужно иметь одну строку в этом скрипте для каждого расширения файла, которое я хочу gzip. Это нормально, но я надеюсь найти лучший способ

Второй и более важный: он не работает. Хотя -r должен делать эту работу, подкаталоги не изменяются. Файл gzip создается только в верхнем каталоге.

Что мне здесь не хватает?

Кстати: следующее - это ошибка в подробном выводе, верно? При использовании опций -k и -v

-k, --keep        keep (don't delete) input files
-v, --verbose     verbose mode

В подробном выводе говорится, что он заменяет файл, хотя «замена» означает, что исходный файл не существует после замены. В любом случае, это только вывод.

$ ls
  index.html      subdir1  testfile      testfile.css.gz
  javaclass.java  subdir2  testfile.css
$ gzip -fkv *.css
  testfile.css:   6.6% -- replaced with testfile.css.gz
$ ls
  index.html      subdir1  testfile      testfile.css.gz
  javaclass.java  subdir2  testfile.css
11
задан 11 July 2014 в 19:16

6 ответов

можно сделать это с, чтобы цикл нашел, что каждый файл затем сжимает его:

for i in `find | grep -E "\.css$|\.html$"`; do gzip "$i" ; done
7
ответ дан 11 July 2014 в 19:16

Получить список файлов:

find -type f | grep -P '\.js|\.html|\.css'

И к gzip все те файлы:

find -type f | grep -P '\.js|\.html|\.css' | tar cvzf archive.gz -T -
4
ответ дан 11 July 2014 в 19:16

Я использовал бы

find /path/to/dir \( -name '*.css' -o -name '*.html' \) -exec gzip --verbose --keep {} \;

Изменение name к iname, если Вы хотите соответствовать расширениям нечувствительно к регистру (т.е. включать .CSS и/или .HTML расширения). Можно опустить /path/to/dir, если Вы хотите запустить рекурсивный поиск с текущего каталога.

13
ответ дан 11 July 2014 в 19:16

Архивировать все файлы в папке/подпапке рекурсивно:

gzip -r `find . -type f -name "*.html"` 

Для разархивации:

gunzip -r `find . -type f -name "*.gz"` 
0
ответ дан 11 July 2014 в 19:16

Я использовал ответ steeldriver , но мне нравится завершать его с --best и --force опции.

cd в любую папку и вводят этот код. Все Ваше соответствие файлам будет gzipped.

find . \( -name '*.css' -o -name '*.js' \) -exec gzip --verbose --keep --best --force {} \;
  • Использование --best для лучшей степени сжатия.
  • Использование --force для перезаписи, не спрашивая, существует ли уже gzipped файл.
2
ответ дан 11 July 2014 в 19:16

Можно использовать globstar.

С globstar опция оболочки включила, все, в чем Вы нуждаетесь, gzip -vk **/*.{css,html}.

Оболочка Bash имеет a globstar опция, которая позволяет Вам записать рекурсивные шарики с **. shopt -s globstar включает его. Но Вы не могли бы хотеть делать это для других команд, которые Вы выполняете позже, таким образом, можно выполнить его и Ваш gzip команда в подоболочке вместо этого.

Эта команда gzips все .css и .html файлы в текущем каталоге любой из его подкаталогов, любой из их подкаталогов, и т.д., сохраняя исходные файлы (-k) и сообщение Вам, что это делает (-v):

(shopt -s globstar; gzip -vk **/*.{css,html})

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

(shopt -s globstar nocaseglob; gzip -vk **/*.{css,html})

; разделяет две команды и внешнее ( ) заставьте их быть выполненными в подоболочке. Установка опции оболочки в подоболочке не заставляет это быть установленным в оболочке вызова. Если Вы действительно хотите включить globstar затем можно работать shopt -s globstar; затем можно просто выполнить команду:

gzip -vk **/*.{css,html}

Можно отключить globstar с shopt -u globstar. Можно проверить, включают ли с этим в настоящее время shopt globstar.

Как это работает

Ключ, к как это gzip работы команды состоят в том, что оболочка выполняет расширения на нем для создания списка каждого файла в иерархии каталогов с именем соответствия, затем передает каждые из этих имен файлов как аргументы gzip.

  • Повороты расширения фигурной скобки **/*.{css,html} в **/*.css **/*.html.
  • Затем globbing разворачивает те два шаблона на названия файлов, доступных под текущим каталогом (**, из-за globstar) чьи имена файлов состоят из чего-либо (*) сопровождаемый указанным суффиксом (.css или .html в этом случае).

Это не соответствует файлам, имена которых запускаются с . или те, которые находятся в каталогах, названных этим путем. У Вас, вероятно, нет никакого подобного HTML и файлов CSS и, если Вы делаете, Вы, вероятно, не хотите включать их. Но если Вы действительно хотите включать их, затем можно соответствовать им явно в зависимости от потребностей. Например, изменение **/*.{css,html} кому: **/{,.}*.{css,html} включает файлы, которые запускаются с . все еще не ища в папках, которые делают.

Если Вы хотите оба файла, имена которых запускаются с . и файлы в каталогах, имена которых запускаются с . чтобы быть включенным, существует более чистый и более простой путь: включите dotglob опция оболочки.

(shopt -s globstar dotglob; gzip -vk **/*.{css,html})

Или если Вы хотите нечувствительное к регистру соответствие и соответствие имен файлов, которые запускаются с .:

(shopt -s globstar nocaseglob dotglob; gzip -vk **/*.{css,html})

Это возможно, хотя очень редкий, для ** расширяться до чего-то слишком долго.

Если у Вас есть огромное количество файлов, названных этим путем, то это может перестать работать с сообщением об ошибке, объяснив, что оболочка не может создать командную строку, потому что это было бы слишком длинно. (Даже с тысячами файлов, это обычно не проблема.)

gzip не будет назван вообще, таким образом, Вы не получите полусделанное задание.

Если эта ошибка происходит, или если Вы волнуетесь по поводу этого, можно использовать find с -exec, любой как steeldriver описывает{} \;) или поскольку я описываю ниже (с {} +).

Можно использовать find с -exec действие и + для эффективности.

gzip управляйте, чтобы поддержки, являющиеся именами нескольких файлов, были сжаты. Но это find команда, хотя это работает хорошо и не будет медленно, если у Вас нет многих файлов, работает gzip управляйте однажды для каждого файла:

find . \( -name \*.css -o -name \*.html \) -exec gzip -vk {} \;

Это работает, и можно определенно использовать его. (. поиски из текущего каталога. Помимо этого, это - действительно немного отличающийся способ записать команду в очень хорошем ответе steeldriver; можно использовать, какой бы ни стиль Вы предпочитаете.)

Можно также сделать find передайте несколько имен файлов gzip и выполненный это только так же много раз по мере необходимости - который является почти всегда только однажды. Чтобы сделать это, использовать + вместо \;. + аргумент должен прибыть сразу после {}. find замены + с дополнительными именами файлов, если таковые имеются.

find . \( -name \*.css -o -name \*.html \) -exec gzip -vk {} +

Хорошо использовать + даже если существует только несколько файлов соответствия, и когда существуют многие из них, это может быть заметно быстрее, чем наличие отдельного gzip вызов для каждого файла.

Как steeldriver упоминания, можно использовать -iname вместо -name соответствовать файлам чей конец имени как .css или .html но с другой капитализацией. Это соответствует включению nocaseglob в globstar- основанный метод, описанный выше.

Наконец, у Вас, вероятно, нет файлов или каталогов соответствия, которые запускаются с .. Но если Вы делаете, find автоматически включает их. Если Вы хотите исключить их (как это происходит с globstar- основанный метод детализировал выше когда dotglob выключено), Вы можете:

find . -not -path '*/.*' \( -name \*.css -o -name \*.html \) -exec gzip -vk {} +

globstar- основанный путь, описанный выше, более прост записать, особенно при исключении каталогов и файлов, которые начинаются ., так как это - значение по умолчанию.

Что не сделать...

Имена файлов могут содержать любой символ кроме разделителя пути / и нулевой символ. Существуют много методов, которые повреждаются на странных именах файлов, и они обычно более сложны, чем методы, это всегда просто работает. Таким образом, я предлагаю избежать их, даже когда Вы знаете (или думайте, что Вы знаете), они находятся хорошо в Вашей определенной ситуации. И конечно Вы не должны использовать их, если у Вас могли бы быть имена файлов с символами, которые можно рассматривать особенно, включая пробелы.

Возможно безопасно передать вывод по каналу find к другой команде, которая обрабатывает его, если Вы используете -print0 или подобное действие, чтобы заставить это помещать нулевой символ между путями вместо новой строки, и не иначе. Имена файлов могут содержать новые строки (хотя я обескураживаю Вас от преднамеренного именования файлов с ними). A find команда с -print действие - включая находку управляет без явного действия с тех пор -print значение по умолчанию - не производит вывод, который может безопасно быть передан по каналу или иначе предоставлен другой команде, которая выполняет действие с файлами.

Вывод find производит с -print0 действие может безопасно быть передано по каналу к xargs -0 ( -0 флаг говорит xargs ожидать разделенный от пустого указателя вход).

1
ответ дан 11 July 2014 в 19:16

Другие вопросы по тегам:

Похожие вопросы: