Это хороший способ создавать уникальные папки на основе измененных дат? - PullRequest
1 голос
/ 10 июля 2020

У меня есть папка с изображениями. Я хотел бы создать папки для каждого в зависимости от того, когда это изображение (или файл) было изменено. Это хороший способ сделать это в bash? Код работает, но я все еще новичок и не уверен, есть ли лучшие способы.

ls -l | sort -k8n -k6M -k7n | tr -s ' ' | cut -d ' ' -f6-8 | uniq | sed '/^$/d'| parallel -j 24 date --date={} +"%Y-%m-%d"| parallel -j 24 mkdir {}

Объяснение кода:

  1. ls -l # найдите файлы и скажите мне дата изменения.
  2. sort -k8n -k6M -k7n # сортировать значения по столбцу 8 (числовой формат c), затем 6 (формат - месяц), затем 7 (числовой формат c).
  3. tr -s ' ' # усечь все пробелы до одного пробела.
  4. cut -d ' ' -f6-8 # вырезать текст по разделителю "" (т.е. пробелу) и сохранить столбцы 6-8.
  5. uniq # сохранить только уникальные значения
  6. sed '/^$/d' # удалить пустые строки.
  7. parallel -j 24 date --date={} +"%Y-%m-%d" # принять ввод и параллельный процесс в 24 задания. Затем преобразуйте ввод даты (исходящий из {}) в формат ГГГГ-ММ-ДД.
  8. parallel -j 24 mkdir {} # создать 24 задания, которые создают папки на основе вывода предыдущей команды ({}).

1 Ответ

1 голос
/ 10 июля 2020

Есть много более простых и менее подверженных ошибкам способов сделать это. Если у вас GNU-версия date(1), например:

#!/usr/bin/env bash
shopt -s nullglob
declare -A mtimes
# Adjust pattern as needed
for file in *.{png,jpg}; do
    mtimes[$(date -r "$file" +'%Y-%m-%d')]=1
done
mkdir "${!mtimes[@]}"

Здесь используется ассоциативный массив bash для хранения всех временных меток, используемых для создания новых каталогов из и затем делает их все сразу с помощью одного mkdir.

И поскольку я упомянул, что предпочитаю делать это в чем-то отличном от чистой оболочки в комментарии, tcl однострочный:

tclsh8.6 <<'EOF'
file mkdir {*}[lsort -unique [lmap file [glob -nocomplain -type f *.{png,jpg}] { clock format [file mtime $file] -format %Y-%m-%d }]]
EOF

или perl:

perl -MPOSIX=strftime -e '$mtimes{strftime q/%Y-%m-%d/, localtime((stat)[9])} = 1 for (glob q/*.{png,jpg}/); mkdir for keys %mtimes'

Оба из них имеют то преимущество, что не требуют специальной c реализации date (опция -r не является POSIX; не уверен, насколько широко она поддерживается за пределами версии GNU coreutils) или bash 4+ (проблема, если вы используете, скажем, Ma c (я думаю, они по-прежнему идут с perl, по крайней мере, до следующих версий OS X или двух)).

...