it-swarm-pt.com

Como altero os carimbos de data e hora da pasta recursivamente para o arquivo mais recente?

Eu queria saber se alguém sabe como alterar os carimbos de data/hora das pastas recursivamente com base no carimbo de data e hora mais recente encontrado nos arquivos dessa pasta.

Então, por exemplo:

 jon no UbuntuPanther:/media/media/MP3s/Foo Fighters/(1997-05-20) A cor e a forma $ ls -alF 
 total de 55220 
 drwxr-xr -x 2 jon jon 4096 30-08-2010 12:34 ./[.____.{drwxr-xr-x 11 jon jon 4096 2010-08-30 12:34 ../[.____.{-rw-r --r-- 1 jon jon 1694044 2010-04-18 00:51 Foo Fighters - Doll.mp3 
 - rw-r - r-- 1 jon jon 3151170 2010-04-18 00:51 Foo Fighters - Enough Space.mp3 
 - rw-r - r-- 1 jon jon 5004289 2010-04-18 00:52 Foo Fighters - Everlong.mp3 
 - rw-r - r - 1 jon jon 5803125 2010-04-18 00:51 Foo Fighters - Stars de fevereiro.mp3 
 - rw-r - r-- 1 jon jon 4994903 2010-04-18 00:51 Foo Fighters - Ei, Johnny Park! .Mp3 
 - rw-r - r-- 1 jon jon 4649556 2010-04-18 00:52 Foo Fighters - Monkey Wrench.mp3 
 - rw-r- -r-- 1 jon jon 5216923 2010-04-18 00:51 Foo Fighters - My Hero.mp3 
 - rw-r - r-- 1 jon jon 4294291 2010-04-18 00:52 Foo Fighters - My Poor Brain.mp3 
 - rw-r - r-- 1 jon jon 6778011 2010-04-18 00:52 Foo Fighters - New Way Home. mp3 
 - rw-r - r-- 1 jon jon 2956287 2010-04-18 00:51 Foo Fighters - See You.mp3 
 - rw-r - r-- 1 jon jon 2730072 2010-04-18 00:51 Foo Fighters - Up in Arms.mp3 
 - rw-r - r-- 1 jon jon 6086821 2010-04-18 00:51 Foo Fighters - andando depois de você .mp3 
 - rw-r - r-- 1 jon jon 3033660 2010-04-18 00:52 Foo Fighters - Wind Up.mp3 

A pasta "(20/05/1997) A cor e a forma" teria seu carimbo de data e hora definido para 18/04/2010 00:52.

16
MonkeyWrench32

Você pode usar touch -r Para usar o registro de data e hora de outro arquivo em vez da hora atual (ou touch --reference=FILE)

Aqui estão duas soluções. Em cada solução, o primeiro comando altera a hora da modificação do diretório para a do arquivo mais novo imediatamente abaixo dele, e o segundo comando examina a árvore de diretórios inteira recursivamente. Mude para o diretório (cd '.../(1997-05-20) The Colour and The Shape') antes de executar qualquer um dos comandos.

No zsh (remova o D para ignorar arquivos de ponto):

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

No Linux (ou mais geralmente com 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-)" .

No entanto, observe que esses não assumem caracteres de nova linha nos nomes dos arquivos.

21

apenas use

find . -exec touch {} \;
3
Daz

Isso não é "recursivamente", apenas altera todos os carimbos de data e hora em uma pasta. Se é isso que você quer dizer, há duas etapas.

stat -c '%Y' filename produzirá o registro de data e hora de filename e stat -c '%Y %n' * produzirá o carimbo de data e hora de cada arquivo na pasta, portanto, ele encontrará o nome do arquivo modificado mais recentemente na pasta atual:

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

Pensando bem, há uma maneira caminho mais fácil de obter o carimbo de data/hora mais alto na pasta:

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

Então você deseja alterar todos os arquivos da pasta para que tenham o mesmo registro de data e hora desse arquivo. touch -r foo bar mudará bar para ter o mesmo registro de data e hora modificado que foo, portanto, todos os arquivos da pasta mudarão para o mesmo registro de data e hora modificado que o arquivo modificado mais recentemente:

touch -r "$mostrecent" *

Portanto, o one-liner é:

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

Eu montei o trabalho e agora:

Este seria um script que altera todos os diretórios dentro de /tmp/test/ para o registro de data e hora do arquivo mais recente dentro de cada diretório:

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

você pode adicionar alguns arquivos de teste em/tmp assim:

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

Peguei o comando zG do @Gilles e o aprimorei para trabalhar em subpastas, mas parece que o zsh é terrivelmente ineficiente para a parte **/* (FDod).

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

As aspas permitem que as entradas do diretório que contêm espaços e guias funcionem corretamente. O FD faz com que ele encontre diretórios não vazios, incluindo os que começam com., O od faz com que ele pesquise da maneira profundidade primeiro, para que a pasta pai seja registrada com data e hora seja atualizado corretamente.

Ao testar, notei que o desempenho e a pegada de memória para **/* (FDod) eram insanos (mais de 1,4 GB para apenas pastas de 650k) e liam todo o conteúdo antes de começar a tocar nas pastas. Depois de substituí-lo por localizar/ler, ficou muito mais rápido, não queimava memória e começou quase imediatamente.

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

Se você não o estiver executando em um script, substitua "$ @" pelas pastas das quais deseja executá-lo.

0
Aaron Queenan

Eu uso esse script para definir recursivamente os carimbos de data e hora da pasta para o conteúdo mais recente. (É muito semelhante à resposta 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