Move apenas os últimos 8 arquivos em um diretório para outro diretório

7

Estou tentando mover os últimos 8 arquivos do diretório Documents para outro diretório, mas não quero movê-los um por um para esse diretório específico. É possível movê-los com um substituto do comando tail , mas para diretórios em vez de arquivos? Quer dizer, eu gostaria de fazer isso com algo como tail -8 ./Documents | mv ./Anotherdirectory ou com mv tail -8 ./Documents ./Anotherdirectory .

Na verdade, estou procurando uma maneira inteligente de mover os últimos 8 arquivos (listados em ls ) rapidamente (sem digitar cada nome) para o outro diretório. Alguma sugestão?

    
por Sandra Ross 15.11.2016 / 18:20

3 respostas

7

Você pode usar for , que faz um loop nos arquivos de forma ordenada e nos permite evitar a análise da saída de find ou ls , para evitar problemas com espaços e outros caracteres especiais em nomes de arquivos. Muito obrigado ao @muru por melhorar isso:)

i=0; j=$(stat ~/Documents/* --printf "%i\n" | wc -l); for k in ~/Documents/*; do if (( (j - ++i) < 8 )); then echo mv -v "$k" ~/AnotherDirectory; fi; done 

Teste primeiro com echo , depois remova echo para realmente mover os arquivos.

Como um script:

#!/bin/bash
i=0
j=$(stat ~/Documents/* --printf "%i\n" | wc -l )
for k in ~/Documents/*; do
  if (( (j - ++i) < 8 )); then
    echo mv -v -- "$k" ~/AnotherDirectory
  fi
done

novamente, remova echo após o teste para mover os arquivos para real

Explicação

por Zanna 15.11.2016 / 20:25
3

Você pode fazer coisas assim usando a substituição de comandos. No Bash:

mv $(ls -d [sort options] source/* | tail -n8) destination

O $(command) executará o que estiver contido nele e substituirá a saída de texto no comando externo. Esse comando ls imprimirá o caminho para cada arquivo no diretório de origem, classificado de acordo com os sinalizadores que você especificar, um por linha, portanto, tail pode levar apenas os últimos. Assim, o acima seria expandido para

mv source/file1 source/file2 source/file3 ... source/file8 destination

Você pode executar apenas ls -d [sort options] source/* | tail -n8 para ver quais arquivos serão copiados.

Dependendo de como você está solicitando a saída de ls e a nomenclatura de arquivos, você pode fazer o que procura simplesmente usando apenas uma variante de mv source/name_* destination para copiar tudo começando com "name_" "para o diretório de destino.

EDITAR: O acima quebra quando há espaços nos nomes dos arquivos. Uma alternativa mais complicada que resolve isso seria

ls -d1 [sort options] source/* | tail -n8 | tr '\n' '
mv $(ls -d [sort options] source/* | tail -n8) destination
' | xargs --null mv -t destination

embora ainda faça uso da análise de ls output para obter classificação em qualquer ordem que não seja alfabética.

    
por t-mager 15.11.2016 / 19:18
1

semelhante à sugestão do t-mager, você pode usar as opções de ordenação ls e pegar os últimos 8 arquivos em uma lista e estes são seus arquivos:

1 10 2 3 4 5 6 7 8 9

use o seguinte comando:
for n in 'ls|tail -8'; do mv $n ~/temp; done

    
por xortion 17.11.2016 / 21:02