Formato extraño de fecha en script bash

Formato extraño de fecha en script bash

Estoy trabajando en un script para ordenar mi carpeta de descargas por la fecha en que se crearon los archivos. Este es el script que estoy usando:

#!/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 -

El nombre de la carpeta creada por este script es lo Junque me lleva a creer que se está produciendo algún tipo de conversión en alguna parte.

Si hago solo un

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

La fecha se muestra 19062014correctamente.

Este es el resultado de un bash -xguión:

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

La funcionalidad que estoy buscando es que el script mueva los archivos a carpetas denominadas 19_06_2014, 20_06_2014etc. según cuándo se creó el archivo.

Respuesta1

Sugeriría usar un formato de fecha como 2014-06-19. De esa manera lslos mostraría en orden cronológico.

En un sistema 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

Con zshcualquier sistema:

#! /bin/zsh -
zmodload zsh/stat || exit

cd ~/Downloads &&
  for file (./*(ND.)) {
    zstat -A date -F %F +mtime $file &&
      mkdir -p $date &&
      mv $file $date
  }

Respuesta2

Suposición descabellada: tiene un alias que lsse usa cuando prueba el comando de forma interactiva, y ese alias no se usa en el script. ¿Algo como esto, tal vez?

alias ls="ls --full-time"

Tenga en cuenta que la sabiduría convencional dice que intentar analizar lses una mala idea. Suponiendo que esté en una máquina Linux, podría ser preferible algo como esto:

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

EDITAR: O, como señala Stéphane a continuación, usar findwith -printfes aún mejor. La salida de states un poco más fácil de predecir que la de ls, pero -printfpermite un formato de salida que usted controla completamente.

Respuesta3

Aquí está el código completo

#!/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 -

información relacionada