Пакетный файл перемещается в структуру каталогов на основе имени файла

Я пишу сценарий для перемещения файлов в каталоги на основе имени файла. Файлы имеют yyyyddmm-xxxxxxx.jpg . Желаемая структура каталогов находится в формате 2013/01 Jan/31 . Я не могу правильно определить date с форматом пробела между месяцем и именем месяца. Когда я пытаюсь использовать формат +%Y/%m %b , я получаю это сообщение об ошибке:

date: дополнительный операнд `% b ''

Я пробовал двойные и одинарные кавычки, но безуспешно. Однако date +"%Y/%m %b/%d" отлично работает в sh :

2013/10/27 окт.

Кроме того, есть ли лучший способ генерировать имя каталога, чем использовать переменные MOVEDIRSTR и MOVEDIR (см. Скрипт)?

Вот мой текущий скрипт:

 FLIST=`ls "$IMGDIR" | grep -E '^.*\.jpg$'` # If there are files to move if [ -n "${FLIST}" ]; then # For each file while read -r line; do # Parse filename to YYYY/mm Mmm/Dd echo $line MOVEDIRSTR=`sed -r -e 's:([0-9]{4})([0-9]{2})([0-9]{2}).*:date -d \1-\2-\3 +%Y/%m_%b/%d:' <<< "$line"` MOVEDIR=`$MOVEDIRSTR` # If a directory does not exist, create it [ -d "$ARCHIVEDIR/$MOVEDIR" ] || (mkdir -p "$ARCHIVEDIR/$MOVEDIR") # Move file into YYYY/mm Mmm directory # mv -f "$IMGDIR/$line" "$ARCHIVEDIR/$MOVEDIR" done <<< "$FLIST" fi 

  • Переименование файла в тот момент, когда он отображается в папке
  • Вывод NamingVariable для нескольких файлов в сценарии Bash
  • Можно ли разделить файл и добавить части с одинаковым расширением в один лайнер?
  • Переименуйте только один файл в каждом каталоге, исходя из условия
  • UNIX переместить имя файла с помощью sysdate
  • Помощь переименованию папки в соответствии с датой
  • Уникальное имя файла для разных файлов
  • Добавить расширение ко всем файлам в каталоге, содержащем точную строку
  • 3 Solutions collect form web for “Пакетный файл перемещается в структуру каталогов на основе имени файла”

    Вы должны указать формат на сегодняшний день после знака + .

     $ date +"%Y/%m %b" 2013/10 Oct 

    Относительно переменных. $MOVEDIRSTR кажется ненужным.

     MOVEDIR=$(sed -r -e 's:([0-9]{4})([0-9]{2})([0-9]{2}).*:date -d \1-\2-\3 +%Y/%m_%b/%d:' <<< "$line") 

    Поскольку с помощью $FLIST вы разбираете даты из этого каталога, я не вижу более чистого способа.

    ОБНОВЛЕНИЕ # 1

    Учитывая обратную связь OP в комментариях ниже, он использует устройство QNAP и, вероятно, имеет приведенную в действие версию этих команд, предоставленную BusyBox. Если вы посмотрите на команду date так: ls -l /bin/date это, вероятно, ссылка на исполняемый файл busybox или что-то подобное. Эти команды не являются полнофункциональными, следовательно, ваши проблемы.

    Он подтвердил это:

    Возможно Вы правы. Моя дата – это собственный исполняемый файл, но / bin / sed -> busybox

    Учитывая ограничения, описанные выше методы могут не работать, поскольку вы работаете с ограниченным набором функций с помощью этих инструментов.

    Прежде всего, я бы использовал glob, чтобы избежать разбора ls и получения списка файлов .jpg в этом кольцевом режиме. Во-вторых, вы можете использовать оболочку (без необходимости sed ) для извлечения компонентов даты:

     shopt -s nullglob for file in "$IMGDIR"/*.jpg; do file_name="$(basename file)" printf "%s\n" "$file_name" numbers="${file%-*}" year="${numbers%[0-9][0-9][0-9][0-9]}" monthday="${numbers#[0-9][0-9][0-9][0-9]}" month="${monthday%[0-9][0-9]}" day="${monthday#[0-9][0-9]}" movedir="$(date -d "$year-$month-$day" +"%Y/%m %b/)" movefile="$(date -d "$year-$month-$day" +"%Y/%m %b/%d)" [ -d "$ARCHIVEDIR/$movedir" ] || mkdir -p "$ARCHIVEDIR/$movedir" mv "$file" "$movefile" done 

    Это предполагает, конечно, что ваша команда date имеет достаточно полный набор функций, поскольку вы упомянули, что это отдельный исполняемый файл из BusyBox. Он также сломается, если длина строки даты не составляет 8 цифр.

    см., может ли следующее решить часть извлечения и форматирования даты:

     $ f=20130131-abcdefgh.jpg $ [[ $f =~ ^([[:digit:]]{4})([[:digit:]]{2})([[:digit:]]{2}) ]] $ yyyy=${BASH_REMATCH[1]} $ mm=${BASH_REMATCH[2]} $ dd=${BASH_REMATCH[3]} $ date -d ${yyyy}-${mm}-${dd} +'%Y/%m %b/%d' 2013/01 Jan/31 
    Interesting Posts
    Linux и Unix - лучшая ОС в мире.