SED и REGEX для переименования EXIF ​​

Сpaste:

list=$(paste -sd, < machines.txt)
1
20.10.2021, 02:43
2 ответа

Зачем изобретать велосипед?

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
3
20.10.2021, 05:49

Использование 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

0
23.10.2021, 17:49

Теги

Похожие вопросы