У меня есть большое количество файлов (десятки тысяч), я должен скопировать от/dir1 до/dir2, но название файла должно измениться как таковой:
СТАРОЕ НАЗВАНИЕ---> НОВОЕ ИМЯ
filename.txt---> bob_filename_1253.txt
Где боб является uid, который владеет файлом, и 1253 является прошлым разом, когда он был изменен.
Я в настоящее время достигаю этого со сценарием Python что циклы через каждый файл и затем CP это новому месту назначения, создавая новое имя файла посредством строкового разрезания.
ОДНАКО это занимает мучительное количество времени. Существует ли инструмент для очистки, более быстрый способ достигнуть этого?
Заранее спасибо!
Принятие Вас запускается с пустого dir2
так, чтобы можно было скопировать файлы с dir1
кому: dir2
без конфликта и затем переименовывают их, я попробовал бы что-то вроде этого:
printf '%s\0' dir1/*.txt | xargs -r0 cp -np -t dir2/
выполнить копию, затем
cd dir2/
printf '%s\0' *.txt | xargs -r0 rename -n -- '
$_ = join "_", ( getpwuid( (stat $_)[4] ) )[0], $_, (stat $_)[9]
'
переименовать (удаляют -n
от rename
управляйте, после того как Вы довольны предложенными изменениями).
Хотя это чаще всего используется для простого s/pattern/replacement/
смены имени, основанное на Perl rename
команда, доступная в текущих версиях Ubuntu, может на самом деле переименовать файлы на основе в значительной степени произвольных выражений Perl.
В этом случае мы можем использовать Perl, встроил stat
получить числовой UID и mtime, и затем использовать getpwuid
поворачивать UID к имени пользователя. (stat $_)[9]
время изменения (mtime) в секунды эпохи - если Вам нужно оно в другом формате, можно использовать POSIX::strftime
или один из нескольких других модулей управления времени.
Следующий сценарий должен сделать задание. Попробуйте его и когда Вы будете удовлетворены результатами, удалите комментарий #
перед cp -p "$oldpath""$f9" "$newpath""$new"
сделать фактическое задание.
Сценарий создаст файл в Вашем названном корневом каталоге ls_file.txt
. Этот файл необходим для хранения вывода ls -l "$oldpath"
команда и сценарий должны будут читать из него во время выполнения. После того, как сценарий заканчивает выполняться, ls_file.txt
файл больше не необходим, и можно удалить его.
Чтобы создать и использовать файл сценария, выполните эти шаги:
Создайте и отредактируйте файл сценария в своем корневом каталоге путем выполнения следующей команды в терминале:
nano ~/my_script.sh
Скопируйте и вставьте следующий код в редактора, изменяющегося /full/path/to/old/directory/
с полным путем к Вашему /dir1
каталог и /full/path/to/new/directory/
к полному пути к Вашему /dir2
каталог:
#!/bin/bash
oldpath="/full/path/to/old/directory/"
newpath="/full/path/to/new/directory/"
ls -l "$oldpath" > "ls_file.txt"
while read f1 f2 f3 f4 f5 f6 f7 f8 f9
do
mod="${f6}${f7}${f8}"
mod2=$(echo "$mod" | tr -d ' :')
name="${f9%.*}"
ext="${f9##*.}"
new="$f3""_""$name""_""$mod2"".""$ext"
echo "$f9"" ---> Will be renamed ---> ""$new"
echo "----------------------------"
# cp -p "$oldpath""$f9" "$newpath""$new"
done < "ls_file.txt"
Сохраните файл сценария и выйдите, редактор путем нажатия Ctrl + X затем нажимают Y.
Сделайте исполняемый файл файла сценария путем выполнения следующей команды в терминале:
chmod +x ~/my_script.sh
Запустите скрипт путем выполнения следующей команды в терминале:
bash ~/my_script.sh
Готово
Как это работает?
Запущение скрипта из моего корневого каталога на тестовом каталоге dir1/
который содержит один файл file.txt
и тестовый каталог dir2/
который пуст при определении oldpath="/home/raffa/test/dir1/"
и newpath="/home/raffa/test/dir2/"
, следующий процесс является примером того, как сценарий работает:
ls -l /home/raffa/test/dir1/
выполняется и вывод записан в названный файл ls_file.txt
который будет затем содержать атрибуты и названия файлов в dir1/
в этом случае один файл file.txt
как так:-rw-r--r-- 1 raffa raffa 0 Jan 25 19:49 file.txt
-rw-r--r--
режим файла.1
количество ссылок.raffa
имя владельца.raffa
имя группы.0
размер файла.Jan 25 19:49
(три поля), дата и время последнего изменения.file.txt
название файла.
Сценарий считает содержание dir1/
от ls_file.txt
линию за линией и разделение каждая строка в поля (девять всего) и присваивает значение каждого поля к переменной f1 f2 f3 f4 f5 f6 f7 f8 f9
.
mod="${f6}${f7}${f8}"
присвоит дату последнего изменения и время, сохраненное в переменных f6 f7 f8
к переменной mod
таким образом, это будет содержать значение как так:
Jan2519:49
mod2=$(echo "$mod" | tr -d ' :')
примет значение переменной $mod
, удалите любые пробелы и двоеточия :
и присвойте его переменной mod2
таким образом, это будет содержать значение как так:Jan251949
name="${f9%.*}"
присвоит имя файла без расширения переменной name
таким образом, это будет содержать значение как так:file
ext="${f9##*.}"
присвоит расширение файла без имени к переменной ext
таким образом, это будет содержать значение как так:txt
new="$f3""_""$name""_""$mod2"".""$ext"
отформатирует новое имя файла как owner_name_lastmodified.extension
и присвойте его переменной new
таким образом, это будет содержать значение как так:raffa_file_Jan251949.txt
cp -p "$oldpath""$f9" "$newpath""$new"
скопирует исходный файл file.txt
от dir1/
кому: dir2/
переименование его к raffa_file_Jan251949.txt
и попытается сохранить исходные атрибуты файла во время этого процесса, таким образом, он выполнится как так:cp -p /home/raffa/test/dir1/file.txt /home/raffa/test/dir2/raffa_file_Jan251949.txt
Этот процесс будет повторен для всех файлов в dir1/
с любым расширением.
Всего наилучшего