Algum método melhor do que este para classificar arquivos pela data de criação?

Algum método melhor do que este para classificar arquivos pela data de criação?

Eu precisava exibir uma lista de diretórios classificados por data de criação e criei esse trecho de código que achei bastante inteligente. Existe uma maneira mais óbvia de fazer isso que estou perdendo?

printf "%-20s\t\t\t%-s\n" "DATE" "CASE"
printf "%-20s\t\t\t%-s\n" "----" "----"

find $idir -mindepth 3 -maxdepth 3 -type d -printf "%T@ %Tc\t\t%p\n" \
     | sed "s#${idir}/##" \
     | sort -h \
     | sed "s#^[^ ]* ##"

Exemplo de saída

DATE                                    CASE
----                                    ----
Fri 06 Sep 2013 11:17:41 AM EDT         dir1/Baseline/2013_09_06_11_16_10
Fri 06 Sep 2013 01:44:38 PM EDT         dir2/Baseline/2013_09_06_13_42_48
Sun 08 Sep 2013 05:02:46 PM EDT         dir3/6 Month/2013_09_08_17_02_05
Fri 13 Sep 2013 02:28:30 PM EDT         dir4/Baseline/2013_09_13_14_25_09

Detalhes

O texto acima parecerá exatamente a 3 diretórios do diretório $idir. Em seguida, ele imprime a hora de criação de quaisquer diretórios encontrados nesta profundidade. Em seguida, retiro a $idirparte do caminho da saída (não preciso), classifico-a e, em seguida, corto a %T@parte da saída. Isso foi apenas para que eu pudesse classificar a saída com mais facilidade.

Sem o final, seda saída fica assim:

DATE                                    CASE
----                                    ----
1378480661.2612650000 Fri 06 Sep 2013 11:17:41 AM EDT           dir1/Baseline/2013_09_06_11_16_10
1378489478.3223970000 Fri 06 Sep 2013 01:44:38 PM EDT           dir2/Baseline/2013_09_06_13_42_48
1378674166.7427782000 Sun 08 Sep 2013 05:02:46 PM EDT           dir3/6 Month/2013_09_08_17_02_05
1379096910.4431689000 Fri 13 Sep 2013 02:28:30 PM EDT           dir4/Baseline/2013_09_13_14_25_09

Me mostrando um método mais limpo!

Responder1

Não existe um método bom e portátil para classificar arquivos por hora. Os métodos mais portáteis são:

  • Se você puder assumir que os nomes dos arquivos contêm apenas caracteres imprimíveis, chame ls -ltd.
  • Caso contrário, use perl.

Este é o método clássico para classificar arquivos por data com ferramentas GNU. Você está assumindo que os nomes dos arquivos não contêm nova linha; isso é facilmente corrigido alterando e ligando \npara a opção. Ah, e abandone as ligações indiretas; observe que seu script não funcionará se contiver algum deles, porque sed os interpretará como caracteres especiais.\0sort-zsed$idir#*^$\[

cd "$idir" &&
find -mindepth 3 -maxdepth 3 -type d -printf '%T@ %Tc\t\t%p\0' |
sort -hz |
tr '\0\n' '\n\0' |
sed 's/^[^ ]* //'

A propósito, você está classificando os arquivos pela hora de modificação, não pela hora de criação. A maioria das variantes Unix, exceto OSX, não suportam tempos de criação completos (do sistema de arquivos, passando pelo kernel, até as ferramentas da área do usuário).

A maneira fácil e limpa de classificar arquivos pelo horário de modificação é usar zsh. O qualificador glob omclassifica os arquivos em idade crescente (use Ompara obter primeiro o arquivo mais antigo).

files=(*(om))
echo "The oldest file is $files[-1]"

Para obter alguma saída como a que você mostra, você pode usarzstat.

zmodload zsh/stat
describe () {
  typeset -A st
  zstat -s -H st "$REPLY"
  echo "$st[mtime] $REPLY"
}
: */*/*(/+describe)

informação relacionada