Я пытаюсь сжать все файлы в 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
можно сделать это с, чтобы цикл нашел, что каждый файл затем сжимает его:
for i in `find | grep -E "\.css$|\.html$"`; do gzip "$i" ; done
Получить список файлов:
find -type f | grep -P '\.js|\.html|\.css'
И к gzip все те файлы:
find -type f | grep -P '\.js|\.html|\.css' | tar cvzf archive.gz -T -
Я использовал бы
find /path/to/dir \( -name '*.css' -o -name '*.html' \) -exec gzip --verbose --keep {} \;
Изменение name
к iname
, если Вы хотите соответствовать расширениям нечувствительно к регистру (т.е. включать .CSS
и/или .HTML
расширения). Можно опустить /path/to/dir
, если Вы хотите запустить рекурсивный поиск с текущего каталога.
Архивировать все файлы в папке/подпапке рекурсивно:
gzip -r `find . -type f -name "*.html"`
Для разархивации:
gunzip -r `find . -type f -name "*.gz"`
Я использовал ответ steeldriver , но мне нравится завершать его с --best
и --force
опции.
cd
в любую папку и вводят этот код. Все Ваше соответствие файлам будет gzipped.
find . \( -name '*.css' -o -name '*.js' \) -exec gzip --verbose --keep --best --force {} \;
--best
для лучшей степени сжатия. --force
для перезаписи, не спрашивая, существует ли уже gzipped файл. С globstar
опция оболочки включила, все, в чем Вы нуждаетесь, gzip -vk **/*.{css,html}
.
Оболочка Bash имеет a globstar
опция, которая позволяет Вам записать рекурсивные шарики с **
. shopt -s globstar
включает его. Но Вы не могли бы хотеть делать это для других команд, которые Вы выполняете позже, таким образом, можно выполнить его и Ваш gzip
команда в подоболочке вместо этого.
Эта команда gzip
s все .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
.**
, из-за 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
ожидать разделенный от пустого указателя вход).