Isso pode ser feito facilmente com matrizes bash / ksh93 / zsh:
a=(*)
cp -- "${a[@]: -4}" ~/
Isso funciona para todos os nomes de arquivos não ocultos, mesmo que contenham espaços, tabulações, novas linhas ou outros caracteres difíceis (supondo que haja pelo menos quatro arquivos não ocultos no diretório atual com bash
).
Como funciona
-
a=(*)
Isso cria uma matriz
a
com todos os nomes de arquivos. Os nomes dos arquivos retornados pelo bash são classificados alfabeticamente. (Eu suponho que isso é o que você quer dizer com "ordenada pelo nome do arquivo". ) -
${a[@]: -4}
Isso retorna os quatro últimos elementos da matriz
a
(desde que a matriz contenha pelo menos 4 elementos combash
). -
cp -- "${a[@]: -4}" ~/
Isto copia os últimos quatro nomes de arquivos para o seu diretório pessoal.
Para copiar e renomear ao mesmo tempo
Isso copiará os últimos quatro arquivos somente para o diretório pessoal e, ao mesmo tempo, pré-anexará a string a_
ao nome do arquivo copiado:
a=(*)
for fname in "${a[@]: -4}"; do cp -- "$fname" ~/a_"$fname"; done
Copie de um diretório diferente e renomeie
Se usarmos a=(./some_dir/*)
em vez de a=(*)
, teremos o problema de o diretório ser anexado ao nome do arquivo. Uma solução é:
a=(./some_dir/*)
for f in "${a[@]: -4}"; do cp "$f" ~/a_"${f##*/}"; done
Outra solução é usar um subshell e cd
no diretório da subshell:
(cd ./some_dir && a=(*) && for f in "${a[@]: -4}"; do cp -- "$f" ~/a_"$f"; done)
Quando a subshell é concluída, o shell nos retorna ao diretório original.
Certificar-se de que a encomenda é consistente
A pergunta pede por arquivos "ordenados pelo nome do arquivo". Essa ordem, Olivier Dulac aponta nos comentários, irá variar de um local para outro. Se for importante ter resultados fixos independentes das configurações da máquina, é melhor especificar a localidade explicitamente quando a matriz a
for definida. Por exemplo:
LC_ALL=C a=(*)
Você pode descobrir em qual localidade você está atualmente executando o comando locale
.