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 Jun
que 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 19062014
correctamente.
Este es el resultado de un bash -x
guió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_2014
etc. según cuándo se creó el archivo.
Respuesta1
Sugeriría usar un formato de fecha como 2014-06-19
. De esa manera ls
los 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 zsh
cualquier 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 ls
se 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 ls
es 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 find
with -printf
es aún mejor. La salida de stat
es un poco más fácil de predecir que la de ls
, pero -printf
permite 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 -