Странное форматирование даты в сценарии bash

Я работаю над скриптом, чтобы сортировать папку для загрузки по дате создания файлов. Это сценарий, который я использую:

#!/bin/bash cd ~/Downloads for FILENAME in * do if [[ -f $FILENAME ]]; then date="$(ls -l $FILENAME | tr -s ' ' | cut -d ' ' -f 6 | tr -d '.')" mkdir -vp "$date" find . -maxdepth 1 -type f -name $FILENAME -exec mv {} "$date" \; fi done cd - 

Имя папки, созданной этим скриптом, – это просто Jun который заставляет меня поверить, что где-то происходит какое-то преобразование.

Если я просто

 ls -l test0 | tr -s ' ' | cut -d ' ' -f 6 | tr -d '.' 

дата показывает 19062014 правильно.

Это результат bash -x скрипта:

 sigurd@Goliath ~ -> bash -x clean + cd /home/sigurd/Downloads + for FILENAME in '*' + [[ -f test0 ]] ++ ls -l test0 ++ tr -s ' ' ++ cut -d ' ' -f 6 ++ tr -d . + date=Jun + mkdir -vp Jun mkdir: created directory 'Jun' + find . -maxdepth 1 -type f -name test0 -exec mv '{}' Jun ';' + for FILENAME in '*' + [[ -f test1 ]] ++ ls -l test1 ++ tr -s ' ' ++ cut -d ' ' -f 6 ++ tr -d . + date=Jun + mkdir -vp Jun + find . -maxdepth 1 -type f -name test1 -exec mv '{}' Jun ';' + cd - /home/sigurd 

Функциональность, которую я ищу, заключается в том, что сценарий должен перемещать файлы в папки с именем 19_06_2014 , 20_06_2014 и т. Д. На основе того, когда был создан файл.

3 Solutions collect form web for “Странное форматирование даты в сценарии bash”

Дикая догадка: у вас есть псевдоним для ls , который используется, когда вы пытаетесь выполнить команду в интерактивном режиме, и этот псевдоним не используется в скрипте. Что-то вроде этого, может быть?

 alias ls="ls --full-time" 

Обратите внимание, что общепринятая мудрость гласит, что попытка разобрать ls – плохая идея. Предполагая, что вы на машине Linux, что-то вроде этого может быть предпочтительным:

 stat "$FILENAME" | awk '/^Modify: /{print $2}' 

EDIT: Или, как показывает Стефан, использование find с -printf еще лучше. Результат stat немного легче прогнозировать, чем ls , но -printf позволяет получить выходной формат, который полностью контролируется вами.

Я бы предложил использовать формат даты, например, 2014-06-19 . Таким образом, они продемонстрировали бы их в хронологическом порядке.

В системе GNU:

 #! /bin/bash - cd ~/Downloads && find . -maxdepth 1 -type f -printf '%p\0%TF\0' | while IFS= read -rd '' file && read -d '' date; do mkdir -vp "$date" && mv "$file" "$date" done 

С zsh в любой системе:

 #! /bin/zsh zmodload zsh/stat || exit cd ~/Downloads && for file (./*(ND.)) { zstat -A date -F %F +mtime $file && mkdir -p $date && mv $file $date } 

Вот полный код

 #!/bin/bash cd ~/Downloads for FILENAME in $(find . -maxdepth 1 -type f); do DATE=$(stat "$FILENAME" | awk '/^Modify: /{print $2}') [ ! -d "$DATE" ] && mkdir -vp "$DATE" mv "$FILENAME" "${DATE}/$FILENAME" done cd - 
  • rsync и резервное копирование и изменение часового пояса
  • что такое разрешение jiffie в ядре Linux
  • Как определить, действительно ли cp -u скопировал файл?
  • Временная метка оборудования с использованием PTP
  • Как найти дату создания файла?
  • Как отображать время sadf в формате epoch
  • как запустить время запуска команды и время окончания команды в txt-файле, используя cygwin
  • Возможно ли обновлять измененные времена только без копирования файлов при использовании rsync?
  • Извлеките метки времени и найдите разницу
  • Изменение измененной даты файла в зависимости от даты в имени файла
  • Изменение времени изменения файла для доступа к времени в массовом порядке
  • Linux и Unix - лучшая ОС в мире.