Официальная возможность получить лицензионный софт бесплатно.
Giveaway of the Day
Это не реклама!

Щелкните для получения прогноза по Биробиджану


пятница, 26 октября 2018 г.

bash: список имеющихся расширений файлов в каталоге и подкаталогах

Есть у меня сервер на самбе, вполне себе рабочий. В нем есть поддержка "корзины" (в отличие от микрософтовских серверов). Но вот какая штука: в корзину валятся всякие файлы, в т.ч. и временные. И за рабочий день их может набраться очень много.
Каждую ночь из "корзин" удаляются файлы старше 30 дней и просто очень толстые, а также - временные. Но иногда временных очень уж много. Стало быть, надо не помещать их в корзину вовсе.
Решение очевидно:

(/etc/samba/smb.conf или его инклюд)
[global]
    vfs objects = recycle
    recycle:keeptree=yes
    recycle:repository= .recycle/%U
    recycle:exclude=*.tmp,~*,*.~*

Однако, кроме трёх указанных типов (расширений имён) файлов могут удаляться и самые разные другие, в т.ч. и такие, которым незачем занимать место в "корзине". Просматривать всё вручную - не труЪ. Логично будет сначала составить список имеющихся расширений, а уже от него плясать. Но наконец-то я нашел ситуацию, для которой в никсах, кажется, нет подходящей утилиты - для выделения только расширения файла. Выделить имя - есть basename, выделить путь - dirname, а вот для выделения суффикса ничего нет.

Покопался, нашел замечательно:

(чего-то там) |awk -F . '{print $NF}'

Пример самоочевиден: объявляем точку разделителем полей и выводим то, что есть в имени файла правее последней точки. Не очень надежно, если есть файлы без расширения, и не очень быстро из-за лишних обращений к awk, но для моих целей подошло:

# cd /var/samba/share
# find -depth -type f -wholename *recycle/* |awk -F . '{print $NF}'|sort|uniq

На выходе получаем отсортированный список уникальных расширений файлов, попавших в "корзины". Дальше осталось только выбрать самые ненужные и добавить их в список настроек виртуальной файловой системы "корзина".

Кроме того, на любимом StackExchange нашел еще приятное обсуждение по этому поводу.

Ну а для любителей башизмов, использующих встроенные возможности по максимуму, есть вот такая прелесть:

# Из начала строки убираем самое длинное вхождение "*/", получаем имя файла с расширением 
filename="${fullpath##*/}";
# Берем подстроку от начала строки (поз. 0) до позиции, где начинается собственно имя файла
### TM: по сути, именно это делает команда dirname
directory="${fullpath:0:${#fullpath} - ${#filename}}";
# Отрезаем самую короткую подстроку, состоящую из точки и как минимум одного "обычного" символа, с конца имени файла
### TM: по сути, именно это делает команда basename
base="${filename%.[^.]*}";
# Берем подстроку от позиции "длина базового имени" до конца полного имени файла
extension="${filename:${#base} + 1}";
# Если на выходе у нас есть что-то в $extension, но ничего нет в $base, то файл был без расширения
if [[ -z "$base" && -n "$extension" ]]; then
  base=".$extension";
  extension="";
fi
echo -e "Оригинал:\t'$fullpath':\n\tПуть:\t'$directory'\n\tПолное имя файла:\t'$filename'\n\tБазовое имя:\t'$base'\n\tРасширение:\t'$extension'"
Специально оставил даже форматирование, как оно было в оригинале, только комментарии перетолмачил.

1 комментарий:

Пожалуйста, воздержитесь от грубостей и персональных нападок.
Я не против матерщины, но она должна быть уместной и использоваться для выражения эмоций, а не в качестве основного средства выражения мыслей.