renomeia os 10 arquivos modificados mais recentemente no AIX

1

Eu tenho alguns arquivos .xls em um diretório definido (digamos em / A / B). Quero renomear os 10 arquivos mais recentes e acrescentar "-bkp" em seus nomes.

Eu tentei não trabalhar

ls -lt *.xls | head -1 | awk '{print "mv " $9 " "$9-bkp}' | sh

Eu tentei encontrar e -exec mas como obtemos os 10 arquivos modificados mais recentes?

    
por Ahmad 16.05.2016 / 11:53

4 respostas

2

Você deve usar -10 e não -1 como argumento para head , e também precisa de aspas em torno de -bkp , então

 ls -lt *.xls | head -10 | awk '{print "mv " $9 " "$9"-bkp"}' | sh

deve funcionar. E você provavelmente teria percebido se você tivesse tentado remover | sh , então o comando acaba com awk imprimindo os comandos.

    
por 16.05.2016 / 12:47
1

Se você não quiser fazer suposições sobre quais nomes de arquivos de caracteres podem conter, faça o seguinte:

ls -dt ./*.xls | awk -v q="'" -v n=10 '
  function process() {
    if (NR > 1) {
      gsub(q, q "\" q q, file)
      print "mv " q file q, q file "-bkp" q
      if (!--n) exit
    }
  }
  /\// {
    process()
    file = $0
    next
  }
  {file = file "\n" $0}
  END  {process()}' | sh -x

Ou se você tiver zsh :

for f (*.xls(om[1,10])) cp -- $f $f-bkp

Ou

autoload zmv
zmv -C '*.xls(#qom[1,10])' '$f-bkp'
    
por 16.05.2016 / 18:25
0

Se você tiver ksh93 (para as matrizes) e perl (para timestamp / stat), isso funcionará:

files=(*.xls)
# exit early if there are no matching files
[ "$files" = "*.xls" ] && exit 0

for index in ${!files[@]}
do
  t[$index]=$(perl -e '$x=(stat(shift))[9]; print "$x"' "${files[index]}")
done

for i in ${!t[@]}
do
  printf "%d %d\n" ${t[i]} $i
done | sort -rn  | head -10 | while read t i
do
  mv "${files[i]}" "${files[i]}-bkp"
done

Funciona coletando a lista de arquivos * .xls e, em seguida, faz um loop sobre esses arquivos, chamando o perl one-liner para imprimir o último registro de data e hora de cada arquivo, salvando o resultado em um array paralelo t .

Em seguida, faz um loop sobre t, imprimindo o registro de data e hora e o índice de array, direciona para sort para obter os arquivos modificados mais recentemente, canaliza para head para obter o top 10 e retorna sobre essa saída para chamar o comando mv nos arquivos correspondentes.

    
por 16.05.2016 / 18:45
-2

ls tem um parâmetro "sort" que pode ter um valor de "time".

#!/bin/bash
IFS=$'\n'
for file in $(ls *.xls --sort=time|head -n 10);
do
    mv $file $file-bkp
done
unset IFS

As IFS-shenanigans são porque o for-loop se torna mal-educado se você tiver espaços em seus nomes de arquivos. Acredito que existem soluções mais ortodoxas para esse problema, mas minha solução funciona. Você pode remover as linhas que contêm o IFS se você souber que seus nomes de arquivos não contêm espaços.

    
por 16.05.2016 / 12:17