it-swarm-es.tech

¿Cómo cambio las marcas de tiempo de la carpeta de forma recursiva al archivo más nuevo?

Me preguntaba si alguien sabe cómo cambiar las marcas de tiempo de las carpetas de forma recursiva en función de la última marca de tiempo encontrada de los archivos en esa carpeta.

Así por ejemplo:

 jon @ UbuntuPanther:/media/media/MP3s/Foo Fighters/(1997-05-20) El color y la forma $ ls -alF 
 total 55220 
 drwxr-xr -x 2 jon jon 4096 2010-08-30 12:34 ./[.____.font>drwxr-xr-x 11 jon jon 4096 2010-08-30 12:34 ../[.____.font>-rw-r --r-- 1 jon jon 1694044 18/04/2010 00:51 Foo Fighters - Doll.mp3 
 - rw-r - r-- 1 jon jon 3151170 18/04/2010 00:51 Foo Combatientes - Suficiente espacio.mp3 
 - rw-r - r-- 1 jon jon 5004289 18/04/2010 00:52 Foo Fighters - Everlong.mp3 
 - rw-r - r - 1 jon jon 5803125 18/04/2010 00:51 Foo Fighters - Febrero Stars.mp3 
 - rw-r - r-- 1 jon jon 4994903 18/04/2010 00:51 Foo Fighters - Hola, Johnny Park! .Mp3 
 - rw-r - r-- 1 jon jon 4649556 18/04/2010 00:52 Foo Fighters - Monkey Wrench.mp3 
 - rw-r- -r-- 1 jon jon 5216923 18/04/2010 00:51 Foo Fighters - My Hero.mp3 
 - rw-r - r-- 1 jon jon 4294291 18/04/2010 00:52 Foo Fighters - My Poor Brain.mp3 
 - rw-r - r-- 1 jon jon 6778011 18/04/2010 00:52 Foo Fighters - New Way Home. mp3 
 - rw-r - r-- 1 jon jon 2956287 18/04/2010 00:51 Foo Fighters - See You.mp3 
 - rw-r - r-- 1 jon jon 2730072 18/04/2010 00:51 Foo Fighters - Up in Arms.mp3 
 - rw-r - r-- 1 jon jon 6086821 18/04/2010 00:51 Foo Fighters - Caminando después de ti .mp3 
 - rw-r - r-- 1 jon jon 3033660 18/04/2010 00:52 Foo Fighters - Wind Up.mp3 

La carpeta "(1997-05-20) The Color and The Shape" tendría su marca de tiempo establecida en 2010-04-18 00:52.

16
MonkeyWrench32

Puede usar touch -r Para usar la marca de tiempo de otro archivo en lugar de la hora actual (o touch --reference=FILE)

Aquí hay dos soluciones. En cada solución, el primer comando cambia el tiempo de modificación del directorio al del archivo más nuevo inmediatamente debajo de él, y el segundo comando examina el árbol de directorios completo de forma recursiva. Cambie al directorio (cd '.../(1997-05-20) The Colour and The Shape') antes de ejecutar cualquiera de los comandos.

En zsh (elimine el D para ignorar los archivos de puntos):

touch -r *(Dom[1]) .
touch -r **/*(Dom[1]) .

En Linux (o más generalmente con GNU find):

touch -r "$(find -mindepth 1 -maxdepth 1 -printf '%T+=%p\n' |
            sort |tail -n 1 | cut -d= -f2-)" .
touch -r "$(find -mindepth 1 -printf '%T+=%p\n' |
            sort |tail -n 1 | cut -d= -f2-)" .

Sin embargo, tenga en cuenta que esos no asumen caracteres de nueva línea en los nombres de archivo.

solo usa

find . -exec touch {} \;
3
Daz

Eso no es "recursivamente", solo está cambiando todas las marcas de tiempo en una carpeta. Si eso es lo que quieres decir, hay dos pasos.

stat -c '%Y' filename generará la marca de tiempo de filename y stat -c '%Y %n' * generará la marca de tiempo y el nombre de archivo de cada archivo en la carpeta, por lo que encontrará el nombre del archivo modificado más recientemente en la carpeta actual:

mostrecent="`stat -c '%Y %n' * | sort -n | tail -n1 | cut -d ' ' -f '2-'`"

Pensándolo bien, hay una forma forma más fácil de obtener la marca de tiempo más alta en la carpeta:

mostrecent="`ls -t | head -n1`"

Luego, desea cambiar todos los archivos de la carpeta para que tengan la misma marca de tiempo que ese archivo. touch -r foo bar cambiará bar para que tenga la misma marca de tiempo modificada que foo, por lo que esto cambiará todos los archivos de la carpeta para que tengan la misma marca de tiempo modificada que el archivo modificado más recientemente:

touch -r "$mostrecent" *

Entonces, la frase es:

touch -r "`ls -t | head -n1`" *
3
Michael Mrozek

Puse el trabajo en conjunto y ahora:

Este sería un script que cambia todos los directorios dentro de /tmp/test/ a la marca de tiempo del archivo más nuevo dentro de cada directorio:

#!/bin/bash
if [ -z "$1" ] ; then
  echo 'ERROR: Parameter missing. specify the folder!'
  exit
fi
#MODE=tail # change to newest file
MODE=head # change to oldest file
for d in "$1"/*/; do
  echo "running on $d"
  find "$d" -type d -execdir \
    echo touch --reference="$(find "$d" -mindepth 1 -maxdepth 1 -printf '%T+=%p\n' \
                              | sort | "$MODE" -n 1 | cut -d= -f2-)" "$d" \;
    # remove echo to really run it
done

puedes agregar algunos archivos de prueba en/tmp como este:

mkdir /tmp/test
cd /tmp/test
mkdir d1
mkdir d2
touch d1/text1.txt
sleep 1
touch d1/movie1.mov
touch d2/movie2.mov
sleep 1
touch d2/text2.txt
touch notthis.file
2
rubo77

Tomé el comando @Gilles zsh y lo mejoré para que funcione en subcarpetas, pero parece que zsh es terriblemente ineficiente para la parte **/* (FDod).

# Don't do this
for d in **/*(FDod); do touch -r "$d"/*(Dom[1]) "$d"; done

Las comillas permiten que las entradas de directorio que contienen espacios y pestañas funcionen correctamente. El FD lo hace encontrar directorios no vacíos, incluidos los que comienzan con., El od lo hace buscar en la forma profundidad-primero, de modo que las marcas de tiempo de la carpeta principal actualizarse correctamente.

Al realizar la prueba, noté que el rendimiento y la huella de memoria para **/* (FDod) era una locura (más de 1.4 GB para solo 650k carpetas), y leyó todo antes de comenzar a tocar las carpetas. Después de reemplazarlo con buscar/leer, se volvió mucho más rápido, no quemó memoria y comenzó casi de inmediato.

#! /usr/bin/env zsh
# Do this instead
find "[email protected]" -depth -type d ! -empty -print0 |while IFS= read -r -d ''; do
    touch -r "$REPLY"/*(Dom[1]) "$REPLY"
done

Si no lo está ejecutando en un script, reemplace "$ @" con las carpetas desde las que desea ejecutarlo.

0
Aaron Queenan

Utilizo este script para configurar recursivamente las marcas de tiempo de la carpeta con el contenido más reciente. (Es muy similar a la respuesta de Gilles):

#! /bin/bash

# Change mtime of directories to that of latest file (or dir) under it, recursively
# Empty leaf directories, or dirs with only symlinks get the $default_timestamp

default_timestamp='1980-01-01 00:00:00'

dir="$1"

[ -d "$dir" ] || { echo "Usage: $0 directory" >&2; exit 1; }

find "$dir" -depth -type d | while read d; do
    latest=$(find "$d" -mindepth 1 -maxdepth 1 \( -type f -o -type d \) -printf '%[email protected] %p\n' | sort -n | tail -1 | cut -d' ' -f2-)
    if [ -n "$latest" ]; then
        touch -c -m -r "$latest" "$d" \
            || echo "ERROR setting mtime of '$d' using ref='$f'" >&2
    else
        touch -c -m -d "$default_timestamp" "$d" \
            || echo "ERROR setting mtime of '$d' to default '$default_timestamp'" >&2
    fi
done
0
mivk