Я должен переименовать файлы на своей SD-карте, чтобы смочь скопировать содержание нескольких sub папок к моему жесткому диску. Сначала я должен найти их их расширением .MOD
(Я могу сделать то использование find ./path/*.MOD2
, поскольку они находятся в различных каталогах).
Я должен переименовать их, потому что у них всех есть имена как MOV001.MOD
, MOV002.MOD
, в другом каталоге другие видео, но так же названный. Это было создано моей камерой. После переименования я мог скопировать их одной командой к моему жесткому диску.
Из-за их подлинных имен, когда я использую cp ./path/*.MOD new-path
, результат состоял бы в том, что я перезаписываю столь же названные файлы.
Как я могу решить это?
Этот крошечный сценарий переименовывает файлы, не перемещая их
n=0; for files in dir1/*.MOD dir2/*.MOD dir3/*.MOD; do printf -v new "${files/MOV*./%02d.}" "$((++n))"; echo mv -v "$files" "$new"; done
или больше четко:
#!/bin/bash
n=0
for files in dir1/*.MOD dir2/*.MOD dir3/*.MOD; do
printf -v new "${files/MOV*./%02d.}" "$((++n))"
echo mv -v -- "$files" "$new"
done
Замена dir1
и т.д. с фактическими путями к Вашим каталогам с файлами
Удалить echo
(это должно только протестировать) после проверки, что это дает Вам, что Вы хотите, для фактического переименования файлов.
Это нумерует файлы 01.MOD
, 02.MOD
, и т.д., Если у Вас есть больше чем 99 файлов, замена %02d
с %03d
добираться 001.MOD
и т.д.
n=0
Это просто устанавливает n
как 0
который является, откуда я хочу, чтобы удар начал рассчитывать.
for files in dir1/*.MOD dir2/*.MOD dir3/*.MOD
A for
цикл может выполнить команды многократно на каждом файле в свою очередь. Синтаксис for [variable] in [these things I want to do something to] ; do [command(s)] $[variable]; done
Я назвал переменную files
и найденный Вашими файлами с помощью шарика: *.MOD
расширен оболочкой до любого файла, имя которого заканчивается в .MOD
(*
соответствия любые символы)
printf -v new
printf
может отформатировать новые числа с фиксированной шириной для более легкой сортировки. new
другая переменная - это - новое название файлов.
"${files/MOV*./%02d.}" "$((++n))"
Ссылка на переменную files
от ранее и замена MOV*
(помните *
любой символ) с результатом числа постепенного увеличения $((++n))
(это n
от первой строки сценария поднимитесь к одному каждому разу, когда цикл выполняется на файле), отформатированное использование кода %02d
чтобы к printf
означает десятичное число фиксированной ширины двух цифр 01, 02 и т.д. Шаблон поиска и замены включает .
остановиться *
соответствие целому имени файла и таким образом удаление расширения.
echo mv -v -- "$files" "$new"
Я добавляю echo
только для тестирования - это показывает то, что будет сделано вместо того, чтобы на самом деле делать его. Удалите эхо, когда счастливый результатом для фактического выполнения команды.
mv
переименовывает или перемещает файлы; его синтаксис mv oldname newname
. Я добавил -v
флаг, который говорит mv
быть "подробным" и сообщить о каждом действии. Я добавил --
только для сейфа - это говорит mv
не принять дальнейшие опции, который останавливает любые имена файлов, запускающиеся с -
от того, чтобы быть интерпретируемым как опции к команде - не нужный в Вашем случае, но хорошей практике.
Каждый файл, указанный files
переменная mv
редактор к уникальному имени, созданному в new
переменная. Мы используем $
к ссылочным переменным и они должны быть в "двойных кавычках", чтобы препятствовать тому, чтобы оболочка делала любые другие расширения на именах файлов - это останавливает специальные символы или пробелы в именах файлов от порождения проблем.
Можно скопировать их с рекурсивного каталога (включая все подкаталоги), поиск расширения и переименовать их за один шаг со сценарием ниже.
Взятый из сценариев я использую, чтобы удостовериться, что не перезаписал файлы при копировании их с рекурсивного каталога:
#!/usr/bin/env python3
import os
import shutil
import sys
dr = sys.argv[1]
new_dir = sys.argv[2]
for root, dirs, files in os.walk(dr):
for name in files:
if name.lower().endswith(".mod"): # for your extension
n = 1; name_orig = name
while os.path.exists(new_dir+"/"+name):
name = "duplicate_"+str(n)+"_"+name_orig
n = n+1
newfile = new_dir+"/"+name
shutil.copy(root+"/"+name_orig, newfile)
Скопируйте сценарий в пустой файл, сохраните его как nodupes.py
, выполните его с входом (источник-) и произведите каталог как аргументы:
python3 /path/to/nodupes.py /path/to/sourcedir /path/to/outputdir
Это переименует столь же названные файлы как:
Конечно, вместо duplicate_
, сценарий может быть изменен для использования чего-либо пронумерованного (или просто числа).
Обобщенная версия, не ища одно расширение только, была бы:
#!/usr/bin/env python3
import os
import shutil
import sys
dr = sys.argv[1]
new_dir = sys.argv[2]
for root, dirs, files in os.walk(dr):
for name in files:
n = 1; name_orig = name
while os.path.exists(new_dir+"/"+name):
name = "duplicate_"+str(n)+"_"+name_orig
n = n+1
newfile = new_dir+"/"+name
shutil.copy(root+"/"+name_orig, newfile)