Зачем изобретать велосипед?
jhead
имеет возможность делать именно то, что вы хотите.
-n[format_string] This option causes files to be renamed and/ or mmoved [sic!] using the date information from the Exif header "DateTimeOriginal" field.
Учитываются даже несколько фотографий с одинаковой отметкой времени:
If the target name already exists, the name will be appended with "a", "b", "c", etc, unless the name ends with a letter, in which case it will be appended with "0", "1", "2", etc.
Пример:
jhead -n%Y%m%d-%H%M%S *.JPG
Использование Raku (, ранее известного как Perl _6)
for i in *.JPG; do
j="$(exiftool "$i" |\
raku -e 'for lines.grep(/"File Modification Date/Time"/).split(":", 2).map(*.trim) -> $k,$v {
put( $v.subst(":", "-", :x(1..2)).subst(" ", "T").DateTime ~ ".JPG")
};'
)";
echo cp -iv "$i" "$j";
done
Пример ввода:
footer_divider_test1.JPG footer_divider_test2.JPG
Пример вывода (удалениеecho
):
overwrite 2021-10-21T21:01:31-07:00.JPG? (y/n [n]) y
footer_divider_test1.JPG -> 2021-10-21T21:01:31-07:00.JPG
overwrite 2021-10-21T21:01:31-07:00.JPG? (y/n [n]) y
footer_divider_test2.JPG -> 2021-10-21T21:01:31-07:00.JPG
Вот подход, использующий Raku, язык, ранее известный как Perl6 --, выпущенный как Perl6 в 2015 году; переименован в Raku в 2019 году. В надежде на вызов, входной .JPG
файл (s ), с которого я начинаю, представляет собой графику, которая на самом деле имеет три строки Date/Time
информации (данных. извлекается из строки File Modification Date/Time
выше ). Приведенный выше код начинается с exiftool
вывода (извините, здесь нет jhead
). И поскольку итератор не включен, предостережения, упомянутые @cas, по-прежнему применимы.
Вывод exiftool
передается в Raku, который реализует классическую идиому :lines
, содержащую строку -literal("File Modification Date/Time"
)aregrep
-ped, эти строки split
на :
двоеточии в максимум 2
элементов, и каждый элементtrim
-обрабатывается для удаления пробелов.
Пары элементов назначаются переменным $k,$v
, а вторая ($v
), содержащая дату/время, передается через две процедуры subst()
. Эти подпрограммы A ). преобразовать :x(1..2)
первое -и -второе (дату):
двоеточия в -
дефисы и B ). преобразовать пробел "
" в T
. Причина выполнения этих двух последних настроек заключается в том, что впоследствии подпрограмма Raku .DateTime
распознает ввод как допустимую временную метку ISO 8601.
Почему все это работает по сравнению с sed? Что ж, преимущества использования действительной временной метки ISO 8601 огромны, потому что Raku предоставляет встроенную -поддержку этих объектов (без необходимости использования внешних библиотек ). Самый очевидный результат (прежде всего )заключается в том, что \([[:digit:]]\{4\}\):\([[:digit:]]\{2\}\):\([[:digit:]]\{2\}\)
гранж устраняется.
Во-вторых, теперь у вас есть доступ к встроенным -в подпрограммы DateTime Раку, таким как:
year
, метод month
, метод day
, метод formatter
, метод is-leap-year
, метод day-of-month
, метод day-of-week
,метод day-of-year
, метод days-in-month
, метод week
, метод week-number
, метод week-year
, метод weekday-of-month
, метод yyyy-mm-dd
, метод mm-dd-yyyy
, метод dd-mm-yyyy
, метод daycount
, метод IO
, метод earlier
, метод later
. Допустим, вам нужна только дата в формате YYYY -MM -DD (ISO 8601 ). Это просто :просто вставьте подпрограмму .yyyy-mm-dd
в цепочку методов после .DateTime
. Или как насчет дня --года? просто вставьте подпрограмму .day-of-year
в цепочку методов после .DateTime
.(Или собственный формат даты? Используйте дату .formatter
для создания собственного). Краткий пример:
СТД (ИСО 8601):
~$ exiftool footer_divider_test1.JPG | raku -e 'for lines.grep(/"Date/Time"/).map(*.split(":", 2 )) { for.map(*.trim) -> $k,$v { say($k => $v.values.subst(":", "-", :x(1..2)).subst(" ", "T").DateTime ) }; };'
File Modification Date/Time => 2021-10-21T21:01:31-07:00
File Access Date/Time => 2021-10-23T09:38:33-07:00
File Inode Change Date/Time => 2021-10-22T23:10:27-07:00
ГГГГ -ММ -ДД (ISO 8601):
~$ exiftool footer_divider_test1.JPG | raku -e 'for lines.grep(/"Date/Time"/).map(*.split(":", 2 )) { for.map(*.trim) -> $k,$v { say($k => $v.values.subst(":", "-", :x(1..2)).subst(" ", "T").DateTime.yyyy-mm-dd ) }; };'
File Modification Date/Time => 2021-10-21
File Access Date/Time => 2021-10-23
File Inode Change Date/Time => 2021-10-22
Наконец, хотя некоторые программисты могут предпочесть сценарии оболочки, Raku предоставляет процедуру dir()
для извлечения имен файлов, а также процедуру rename()
для переименования файлов и каталогов. Эти функции могут быть полезны для реализации сценария на платформах, где классическая оболочка -опосредованный файл -подстановка ограничена и/или отсутствует (см. ссылку SO ниже ).
https://en.wikipedia.org/wiki/ISO_8601
https://docs.raku.org/language/temporal
https://docs.raku.org/type/Dateish
https://stackoverflow.com/questions/69384754/how-do-i-use-raku-e-and-n-with-multiple-file-glob/69400187
https://raku.org