gzip всі файли, не видаляючи їх


11

Мені потрібно зібрати всі файли в dir окремо, включаючи всі файли в підкаталогах, не видаляючи оригінали згодом. Тож скажімо, у мене є index.html, я хочу мати в кінці index.html.gzip І index.html.

Я можу зібрати всі файли в своєму режимі через

gzip -r .

Але я також хочу зберегти оригінальні файли.

Чи можливо це?

Відповіді:


9
find . -type f | \
while read -r x
do
  gzip -c "$x" > "$x.gz"
done

-cПоміщає результат в стандартний висновок і зберігає оригінальні один. Недоліком є ​​те, що вам потрібно знайти файли самостійно. Однак для більш складного переходу можна скористатися find(1), як і вище: .пошук, починаючи з поточного каталогу, і -type fповертає ім'я кожного звичайного файлу.


Чому *.*в ls?

@pooh: *.*відповідає всім регулярно названим файлам, і зазвичай немає каталогів. Звичайно, він працює лише в більшості випадків, і зазвичай не, якщо вам це потрібно. Потім використовуйте findкоманду.
Болдевін

@Boldewyn: питання полягало в тому, щоб зібрати всі файли в режимі. ls *.*не вибиратиме файли типу TODO .

lsне вимагається взагалі : for x in *. Однак використовувати findслід find . -type f | while read -r x.
Призупинено до подальшого повідомлення.

Оновлена ​​відповідь. Дякуємо за -rвключення read.
Болдевін

5
find . -type f -not \( -name '*.gz' -or -name '*[~#]' \) -exec sh -c 'gzip -c "{}" > "{}.gz"' \;

Ви можете легко переключити його, щоб включити те, що ви хочете стиснути ( -name '*.txt -or -name '*.htmlтощо) замість того, як зараз, виключаючи деякі файли (вже стиснуті, резервні та тимчасові файли).

Також обробляє пробіли у назві файлу.

Змініть gzipна echo gzipтестування. Або пропустіть частину -exec разом.

Редагувати: О, я забув зазначити, що це не перевіряє, чи <target>.gzвже існує. Це може бути або не бути проблемою.

Edit2: Гаразд, тут ми переглядаємо щось, що перевіряє наявний файл. Якщо цього, можливо, захочеться. Пробачте, єдиність.

while read file; do if [ ! -f "$file.gz" ]; then echo "Compressing $file"; gzip -c "$file" > "$file.gz"; else echo "Not overwriting $file.gz";  fi  done < <(find . -type f -not \( -name '*.gz' -or -name '*[~#]' \))

Мій find-фуд, можливо, не такий, як міг би бути, можливо, цілком можливо пропустити прямо в пошуку.


1
просто прочитайте, що -name має бути раніше -type, щоб уникнути виклику stat у кожному файлі.

@Ben Має сенс, хороший вклад! Для великих дерев це може бути помітно.
плюндра



Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.