Como mover tudo menos os últimos arquivos?

0

Como posso mover tudo menos os últimos n arquivos, de dir1 para dir2 ?.

Atualmente faço isso, definindo a hora como um valor aproximado para n , no meu caso n=2 a cada 10 minutos.

find /dir1/ -name '*.txt*' -mmin +10 -type f -exec mv "{}" /dir2/ \;

Um comando similar, poderia funcionar, mas não tenho certeza, alguém poderia confirmar como deve adaptar isso?

ls -1tr | head -n -2 | xargs -d '\n' mv -f --
    
por Brethlosze 13.07.2017 / 16:46

3 respostas

2

com zsh :

mv dir1/**/*.txt*(D.om[3,-1]) dir2/

Mudaria os arquivos regulares em dir1 , exceto os 2 modificados mais recentemente para dir2 .

  • **/ : qualquer nível de subdiretório.
  • D : inclua arquivos ocultos e desça em diretórios ocultos.
  • . : somente arquivos regulares (nenhum link simbólico, diretório ...), equivalente para find ' -type f .
  • om : classificar por hora da modificação (a mais recente primeiro como com ls -t ).
  • [3,-1] : somente do terceiro ao último

(você pode emitir um zmodload zsh/files para obter um mv embutido ou usar zargs se você encontrar um problema lista de argumentos muito grande ).

POSIXly, isso simplesmente não pode ser feito sem fazer algumas suposições sobre os nomes dos arquivos, o número de arquivos e o comprimento de seus caminhos.

GNUly (com versões recentes de ferramentas GNU para -z ), você poderia fazer:

find dir1 -name '*.txt*' -type f -printf '%T@\t%p
find dir1 -type f -printf '%T@\t%p
mv dir1/**/*.txt*(D.om[3,-1]) dir2/
' | sort -rnz | tr '\n
find dir1 -name '*.txt*' -type f -printf '%T@\t%p
find dir1 -type f -printf '%T@\t%p%pre%' | sort -rnz |
  tr '\n%pre%' '%pre%\n' |
  tail -n +3 | cut -f2- |
  tr '\n%pre%' '%pre%\n' | xargs -r0 mv -t dir2
' | sort -rnz | tail -zn +3 | cut -zf2- | xargs -r0 mv -t dir2
' '%pre%\n' | tail -n +3 | cut -f2- | tr '\n%pre%' '%pre%\n' | xargs -r0 mv -t dir2
' | sort -rnz | tail -zn +3 | cut -zf2- | xargs -r0 mv -t dir2

Embora o% GNUsort e xargs tenham tido opções -z / -0 há décadas, a adição de -z para cut e tail é bem recente. Se você tem versões mais antigas, você sempre pode fazer:

%pre%

Observe que, embora essas soluções procurem arquivos recursivamente em dir1 (inclusive em subdiretórios), eles não recriarão a mesma estrutura de diretório em dir2 . Isso significa que, por exemplo, se houvesse ambos, dir1/file.txt e dir1/subdir/file.txt , ambos seriam movidos para dir2/file.txt , um sobrescrevendo o outro.

    
por 29.11.2017 / 12:17
2

Como os arquivos com registro de dados serão reunidos em ordem com globs de shell (por exemplo, *.txt ), você poderá usar matrizes (como no bash):

n=2 ## how many of each you want to keep
txtfiles=(*.txt)
auxfiles=(*.txt_aux)
totaltxt=${#txtfiles[@]}
totalaux=${#auxfiles[@]}
movetxt=$((totaltxt-n))
moveaux=$((totalaux-n))
echo mv "${txtfiles[@]:0:movetxt}" /dir/aux2/
echo mv "${auxfiles[@]:0:moveaux}" /dir/aux2/

Remova os dois últimos echo peças quando parecer que está fazendo a coisa certa.

    
por 13.07.2017 / 17:29
1

Uma maneira mais fácil de fazer isso:

mv 'ls -tr sourcedir | head -n -2' destdir 

Nota: Isso pressupõe que você saiba que existem mais de dois arquivos no diretório. Se não tiver certeza, você pode contá-las com ls | wc -l

    
por 29.11.2017 / 22:56