Вопрос или проблема
Я хочу освободить место на своем SSD, и затем увидел свою гигантскую папку с записями OBS. Многие из них были ремюксы с mkv
на mp4
. Я хочу удалить файлы mkv
и оставить файлы mp4
. Сначала я подумал сделать rm *.mkv
, но потом вспомнил, что есть некоторые файлы, которые не были ремюкшены, и таким образом остались файлами mkv
. И я хочу сохранить эти файлы.
Вот в чем заключается моя цель: удалить все файлы mkv, если существует другой файл с точно таким же именем но с другим расширением. Я также понимаю, что расширение является именем в Linux, но учитывая тот факт, что в моем случае есть только файлы mp4
и mkv
, я предполагаю, что мы можем просто сослаться на последние три буквы. Но я хотел бы более надежный вариант. Мне также не важны подкаталоги, так как в моем случае их нет.
Я искал это в интернете, и после долгого поиска нашел следующее: Удалить файлы, если условие выполнено
И в ответе предложено следующее:
for file in `find -type f -size +1000000k -name "*.mkv"`; do
# Это удалит расширение mkv
noext=${file::-4}
# Части директорий
parentdir=`echo $file | cut -d"https://superuser.com/" -f2` # Это вернет 'Directories'
if [ -e "./$parentdir/$noext.rar" ]; then
rm -f "./$parentdir/$noext.rar"
fi
done
Я долго смотрел на это, но действительно не смог понять, как изменить это под свои нужды. Я почти ничего не знаю о bash.
Кроме того, если вам нужны примеры (список файлов до и после выполнения необходимых команд), вот они (я также поставил звезду “*” после каждого файла, который должен быть удален для вашего удобства):
Входные данные::
2022-13-64.mp4 (mkv существует, операция не выполнена)
2022-13-64.mkv* (удален, mp4 существует)
2025-01-35.mp4 (mkv существует, операция не выполнена)
2025-01-35.mkv* (удален, mp4 существует)
2027-08-12.mp4 (mkv отсутствует, операция не выполнена)
2004-06-01.mkv (это mkv, но mp4 не существует, операция не выполнена)
Ожидаемый вывод:
2022-13-64.mp4
2025-01-35.mp4
2027-08-12.mp4
2004-06-01.mkv
Также, приоритетнее сохранить mp4
, чем mkv
. Например, если существуют два файла с одинаковым “именем” (то есть, все, что перед mp4
или mkv
), но один является mp4
, а другой mkv
, то mkv
будет удален, а mp4
сохранен. Но иногда это не желательно. Например, иногда существует только mkv
, и нет mp4
с тем же “именем”. В этом случае удаление этого файла не будет выполнено.
Этот переносимый фрагмент кода оболочки обработает файлы в текущем рабочем каталоге (но не в подкаталогах):
for f in ./*.mkv; do
[ -f "${f%.mkv}.mp4" ] && echo rm "$f"
done
На всякий случай, вышеизложенное – это тестовый запуск, он только выводит, что бы он сделал. Если это выглядит нормально, удалите точно строку echo
, чтобы “активировать” этот фрагмент, а затем выполните измененную версию.
Код циклится по именам файлов, полученным в результате расширения шаблона ./*.mkv
. Внутри цикла $f
(который должен быть правильно экранирован) разворачивается в текущее обрабатываемое имя файла; ${f%.mkv}
разворачивается в имя файла без .mkv
в конце; ${f%.mkv}.mp4
разворачивается в имя файла, из которого .mkv
удалено и затем добавлено .mp4
(конкатенировано). [ -f … ]
проверяет, является ли он существующим обычным файлом, и &&
выполняет следующую команду (echo …
в данном случае) если и только если предыдущая команда (то есть наш тест) выполнена успешно.
Обратите внимание, что стандарт ./*.mkv
не соответствует скрытым файлам. В Bash, если вы хотите, чтобы наш фрагмент соответствовал также скрытым файлам, выполните shopt -s dotglob
заранее. Для полноты: shopt -u dotglob
устанавливает стандартное поведение.
Ответ или решение
Для решения вашей задачи по удалению файлов .mkv, если соответствующий файл .mp4 с тем же именем существует в текущей директории, вы можете воспользоваться следующим скриптом на Bash. Я объясню его шаг за шагом, и предоставлю код, который вы можете использовать.
Шаги:
- Цикл по файлам .mkv: Мы перебираем все файлы с расширением .mkv в текущей директории.
- Проверка существования соответствующего файла .mp4: Для каждого .mkv файла мы проверяем, существует ли файл с тем же именем, но с расширением .mp4.
- Удаление файла .mkv: Если файл .mp4 существует, мы удаляем соответствующий .mkv файл.
Код:
for f in ./*.mkv; do
# Проверяем, существует ли .mp4 файл с тем же именем
if [ -f "${f%.mkv}.mp4" ]; then
echo "Удаление: $f" # Эта строка для предварительного просмотра. Удалите echo для реального удаления.
rm "$f" # Удаление файла
fi
done
Объяснение кода:
for f in ./*.mkv; do
: Цикл перебора всех файлов с расширением .mkv в текущей директории.if [ -f "${f%.mkv}.mp4" ]; then
: Проверка существования соответствующего файла .mp4. Здесь${f%.mkv}
удаляет расширение .mkv и оставляет только имя файла.echo "Удаление: $f"
: Эта строка выводит на экран, какой файл будет удалён. Это служит для проверки перед настоящим удалением.rm "$f"
: Если файл .mp4 существует, этот код выполняет удаление файла .mkv.
Важно:
- Перед тем как выполнять реальное удаление, я рекомендую протестировать код с использованием команды
echo
на первой строке, чтобы убедиться, что вы удалите именно те файлы, которые хотите. - После проверки вы можете удалить
echo
, чтобы код удалял файлы.
Заключение:
С помощью этого скрипта вы сможете эффективно освобождать место на SSD, удаляя ненужные .mkv файлы, при этом оставаясь с необходимыми .mp4 файлами. Если у вас есть дополнительные вопросы или требования к скрипту, не стесняйтесь задавать их!