- Вопрос или проблема
- 1.
- 2.
- 3.
- Тегирование файлов
- Поиск файлов по тегам
- Версия 1: Файлы, соответствующие любому из указанных тегов
- Версия 2: Файлы, соответствующие всем указанным тегам
- Очистка тегов
- Удаление тегов
- Ответ или решение
- Как отмечать файлы в системе UNIX с использованием расширенных атрибутов
- Обзор решения
- Требования
- Установка необходимых инструментов
- Создание функций для работы с тегами
- 1. Добавление тегов к файлам и директориям
- 2. Поиск файлов по тегам
- 3. Удаление тегов
- 4. Очистка тегов
- Заключение
Вопрос или проблема
Я пытаюсь выяснить лучшее решение для тегирования файлов в GNU/Linux. Это то, что я пытаюсь достичь. Я загружаю все свои фильмы и сохраняю их на внешнем SSD. Я сортирую их в две директории: “просмотренные” и “к просмотру”. Однако я хочу присвоить каждому фильму атрибуты, такие как (но не ограничиваясь ими): главный актер(ы), режиссер(ы), жанр. Таким образом, если у меня есть большое количество файлов и я хочу посмотреть фильм, снятый Скорсезе, я смогу отобразить только фильмы с тегом “скорсезе”.
Вот некоторые требования, которые у меня есть:
- Я хочу, чтобы решение было независимо от моего локального компьютера. Например, если я возьму свой внешний SSD к другу, у которого тоже система Unix (и установлю необходимое решение для тегов), его компьютер тоже сможет интерпретировать все теги, созданные мной.
- Я хочу иметь вариант командной строки (CLI).
- Если я изменю местоположение файла, тег(и) все равно останутся с файлом.
- Я могу присваивать несколько тегов файлу.
- Я могу тегировать файл любого формата.
- Я также могу тегировать директорию (не только файлы).
Две вещи:
1.
Наиболее нативный способ — это, конечно, использовать функцию многих файловых систем Unix для сохранения того, что называется расширенными атрибутами или просто xattrs. Вы можете запрашивать, устанавливать, изменять и удалять эти атрибуты из файлов, используя командные программы getfattr
и setfattr
(под Linux, не знаю, как это делают в *BSD); их справочные страницы должны быть вам интересны.
Тем не менее, это не действительно так полезно — в конце концов, у вас будет много файлов, которые вы каким-то образом отметили некоторой информацией, но вам придется сидеть на консоли, чтобы попытаться извлечь их снова.
Таким образом, то, что вам действительно нужно, — это не только способ тегирования файлов, вам нужно что-то, чтобы фактически делать что-то полезное с этой информацией, управлять ею и так далее.
2.
То, что вы описываете, функционально является базой данных фильмов, и, как таковая, вероятно, медиасервер является самым полезным решением. Если вы можете ограничить количество возможных платформ до одной (или, возможно, двух), таких как x86_64 (и, возможно, arm64?), вы также можете просто разместить контейнер на своем внешнем жестком диске, который содержит все необходимое для запуска программного обеспечения базы данных фильмов. Таким образом, ваш друг просто может запустить это (не знаю, в каком виде что-то такое существует — может быть, сервер DLNA?). У меня нет опыта с такими вещами.
Так что я бы сделал следующее: сел и написал программное обеспечение, которое вы хотите. Звучит безумно, но это вполне нормально, учитывая, что любое современное оборудование типа PC с Unix на нем будет иметь доступ к как минимум современному Python3.
3.
Как описано выше, вы могли бы использовать расширенные атрибуты файловой системы для хранения информации о файле — внутри самого “файлового системного элемента”. Таким образом, он будет оставаться с файлом, когда вы перемещаете его на диске.
Тем не менее, поскольку, как вы сказали, вы, возможно, захотите запустить какой-то вид GUI/TUI с внешнего диска, в любом случае, в этом не так много пользы. Поэтому простая база данных SQLite (sqlite3
поставляется с каждой установкой Python) подойдет отлично. Затем вы просто напишете короткий инструмент для поиска файла базы данных, поиска медиафайлов относительно этого, затем добавьте несколько функций для сканирования файлов, которые еще не являются частью базы данных, добавьте их, возможно, запросите данные из API IMDB. Конечно, было бы неплохо иметь красивый интерфейс запроса, так что вы могли бы либо сделать “текстовое приключение”, либо использовать Textual
(новое, захватывающее, вероятно, немного экспериментальное) или urwid
; оба являются чистым Python, если я не ошибаюсь, так что выполнение будет тривиальным на разных машинах!
Я предлагаю здесь решение для легкого тегирования файлов, их поиска и редактирования тегов.
После поиска в интернете, на август 2024 года не похоже, что есть активно поддерживаемое программное обеспечение, которое позволяет иметь систему тегирования файлов на любой дистрибутиве Linux (обнадеживающим было TMSU, но, как и у других программ, последний коммит в репозитории сделан несколько лет назад).
Таким образом, расширенные атрибуты (xattrs) действительно могут оказаться достаточно надежным способом достижения этого.
Итак, вот мое решение. Короче говоря, это просто использование команд setfattr
и getfattr
с помощью командных алиасов для облегчения тегирования, поиска, удаления и обеспечения консистентности тегов: addtag
, findtag
, removetag
, cleantag
(некоторые из них могут работать только с Zsh, но совместимость с Bash пытается быть обеспеченной всякий раз, когда это возможно).
Примечание: Я предлагаю использовать пространство имен user.xdg.tags
для xattrs, чтобы тегировать файлы или директории, так как это, похоже, является стандартом во многих приложениях для пользовательских тегов (см. ArchWiki: Пользовательские расширенные атрибуты).
Тегирование файлов
Чтобы тегировать myfile
с mytag1
и mytag2
, мы просто добавляем значение user.xdg.tags
к mytag1,mytag2
, разделяя новые теги запятыми. Ниже приводится команда, используемая таким образом:
addtag mytag1 mytag2 myfile
function addtag()
{ ## Добавить тег(и) к файлу.
## Указанные теги добавляются к строковому значению user.xdg.tags расширенных атрибутов, разделенному запятыми.
## Использование: addtag TAG [...] FILE
tags_existing=$(getfattr -n user.xdg.tags --only-value "$argv[-1]")
setfattr -n user.xdg.tags -v "${tags_existing},${(%j:,:)argv[1,-2]}" "$argv[-1]"
}
Поиск файлов по тегам
Ниже приведен полезный алиас оболочки для поиска файлов или директорий, которые имеют хотя бы один из указанных тегов (Версия 1) или все указанные теги (Версия 2). Это предполагает, что теги являются значениями user.xdg.tags
.
Версия 1: Файлы, соответствующие любому из указанных тегов
Например, чтобы найти все файлы/директории из текущего пути, которые имеют тег, содержащий строку str1
или включает тег, содержащий строку str2
:
findtag str1 str2 ./
- В Bash:
function findtag()
{ # Поиск тегов в пространстве имен user.xdg.tags расширенных атрибутов.
# Использование: findtag TAG [...] PATH
local IFS="|"
find "$*[-1]" -exec getfattr -n user.xdg.tags '{}' \+ 2>/dev/null | grep -Ei "${*[1,-2]}"
}
- В Zsh:
function findtag()
{ # Поиск тегов в пространстве имен user.xdg.tags расширенных атрибутов.
# Использование: findtag TAG [...] PATH
find "$argv[-1]" -exec getfattr -n user.xdg.tags '{}' \+ 2>/dev/null | grep -B 1 -Ei "${(%j:|:)argv[1,-2]}"
}
Единственное отличие между версиями Bash и Zsh — это код для обработки пользовательских тегов.
Версия 2: Файлы, соответствующие всем указанным тегам
Например, чтобы найти все файлы/директории из текущего пути, которые имеют тег, содержащий строку str1
и тег, содержащий строку str2
:
findtag str1 str2 ./
Предупреждение: предполагается Zsh.
function findtag()
{ # Поиск тегов в пространстве имен user.xdg.tags расширенных атрибутов.
# Использование: findtag TAG [...] PATH
find "$argv[-1]" -exec getfattr -n user.xdg.tags '{}' \+ 2>/dev/null | grep -B 1 -Pi "(?<=user.xdg.tags=\")(?=.*${(%j:)(?=.*:)argv[1,-2]})"
}
Очистка тегов
Этот алиас оболочки позволяет избежать дублирования тегов или нежелательных запятых между тегами в строке тегов. Это предполагает, что теги являются значениями user.xdg.tags
.
Предупреждение: предполагается Zsh.
function cleantag()
{ ## Очистить строку тегов файла(ов).
## Теги предполагается рассматривать как подстроки значения пространства имен user.xdg.tags расширенных атрибутов.
## Использование: cleantag FILEPATH
local tags_existing file
for file in "$@"; do
if getfattr -n user.xdg.tags --only-value $file &>/dev/null; then
tags_existing=$(getfattr -n user.xdg.tags --only-value $file)
tags_existing=${tags_existing//,,##/,} # Удаление дублирующихся запятых.
tags_existing=$(echo "$tags_existing" | tr ',' '\n' | sort -u | tr '\n' ',') # Удаление дублирующихся тегов.
tags_existing=${tags_existing/#,/} # Удаление ведущей запятой.
tags_existing=${tags_existing/%,/} # Удаление завершающей запятой.
setfattr -n user.xdg.tags -v "${tags_existing}" $file
fi
done
}
Удаление тегов
Этот алиас оболочки позволяет удалять отдельные теги. Это предполагает, что теги являются значениями user.xdg.tags
.
Предупреждение: предполагается Zsh.
function removetag()
{ ## Удалить тег(и) из файла.
## Указанные теги удаляются из строкового значения пространства имен user.xdg.tags расширенных атрибутов, разделенного запятыми.
## Использование: removetag TAG [...] FILEPATH
local tags_remaining tag
setopt localoptions extendedglob
if getfattr -n user.xdg.tags --only-value "$argv[-1]" &>/dev/null; then
tags_remaining=$(getfattr -n user.xdg.tags --only-value "$argv[-1]")
for tag in "$@[1,-2]"; do
tags_remaining=${tags_remaining//$tag/}
echo "Тег \"${tag}\" и его дубликаты были удалены."
done
tags_remaining=${tags_remaining//,,##/,} # Удаление дублирующихся запятых.
tags_remaining=${tags_remaining/#,/} # Удаление ведущей запятой.
tags_remaining=${tags_remaining/%,/} # Удаление завершающей запятой.
setfattr -n user.xdg.tags -v "${tags_remaining}" "$argv[-1]"
fi
}
Ответ или решение
Как отмечать файлы в системе UNIX с использованием расширенных атрибутов
В современном мире фильмов и медиа острота требований к управлению файлами и метаданными становится все более актуальной. Если вы храните свои фильмы на внешних SSD и хотите отсортировать их по различным меткам, таким как актеры, режиссеры и жанры, то решение с использованием расширенных атрибутов файловой системы (xattrs) является одним из наиболее эффективных методов. В данной статье мы рассмотрим, как успешно внедрить систему тегирования в UNIX-системах.
Обзор решения
Расширенные атрибуты (xattrs) позволяют хранить дополнительные метаданные о файлах и каталогах в самих файловых системах, что делает их переносимыми вместе с файлами. Это означает, что даже если вы переместите свои файлы на другую систему или в другую папку, ваши метки останутся с файлами. Кроме того, xattrs можно использовать с любым типом файлов, что гарантирует универсальность данного решения.
Требования
Для реализации данной системы тегирования вам потребуются следующие инструменты:
- Команды
setfattr
иgetfattr
: Они позволят устанавливать и извлекать расширенные атрибуты. - Клиентская программа для работы с тегами: Мы создадим несколько функций, которые помогут в добавлении, поиске, удалении и очистке тегов.
Установка необходимых инструментов
Для того чтобы начать, убедитесь, что у вас установлены необходимые пакеты:
sudo apt install attr
Создание функций для работы с тегами
1. Добавление тегов к файлам и директориям
Функция addtag
будет использоваться для добавления новых тегов к файлу. Определите эту функцию в вашем .bashrc
файле:
function addtag() {
tags_existing=$(getfattr -n user.xdg.tags --only-value "$1" 2>/dev/null)
if [ -z "$tags_existing" ]; then
setfattr -n user.xdg.tags -v "$2" "$1"
else
setfattr -n user.xdg.tags -v "${tags_existing},$2" "$1"
fi
}
Использование:
addtag myfile "mytag1,mytag2"
2. Поиск файлов по тегам
Функция findtag
позволит вам находить файлы по определенному набору тегов.
function findtag() {
find "$1" -exec getfattr -n user.xdg.tags '{}' \+ 2>/dev/null | grep -Ei "$2"
}
Использование:
findtag ./ "mytag"
3. Удаление тегов
Для удаления тегов воспользуйтесь следующей функцией:
function removetag() {
tags_remaining=$(getfattr -n user.xdg.tags --only-value "$1" 2>/dev/null)
for tag in "${@:2}"; do
tags_remaining=${tags_remaining//,$tag/}
tags_remaining=${tags_remaining//$tag,/}
tags_remaining=${tags_remaining//$tag/}
done
setfattr -n user.xdg.tags -v "$tags_remaining" "$1"
}
Использование:
removetag myfile "mytag1"
4. Очистка тегов
Для очистки лишних запятых и повторяющихся тегов используйте функцию cleantag
:
function cleantag() {
tags_existing=$(getfattr -n user.xdg.tags --only-value "$1")
tags_existing=$(echo "$tags_existing" | tr ',' '\n' | sort -u | tr '\n' ',')
tags_existing=${tags_existing/#,/}
tags_existing=${tags_existing/%,/}
setfattr -n user.xdg.tags -v "$tags_existing" "$1"
}
Использование:
cleantag myfile
Заключение
Система тегирования, основанная на расширенных атрибутах, предоставляет мощный инструмент для управления вашими медиафайлами. Она позволяет удобно организовать вашу коллекцию, обеспечивая сохранение всей информации при переносе файлов на другие устройства. Рассмотренные функции могут быть расширены в соответствии с вашими требованиями. Применив такие решения, вы не только улучшите управление файлами, но и повысите удобство доступа к вашим медиафайлам в любое время и в любом месте.