Como copiar todo quarto arquivo em uma pasta

14

Eu tenho muitos arquivos em uma pasta, nomeados como 00802_Bla_Aquarium_XXXXX.jpg . Agora preciso copiar todos os arquivos 4th para uma subpasta, informando em selected/ .

00802_Bla_Aquarium_00020.jpg <= this one
00802_Bla_Aquarium_00021.jpg
00802_Bla_Aquarium_00022.jpg
00802_Bla_Aquarium_00023.jpg
00802_Bla_Aquarium_00024.jpg <= this one
00802_Bla_Aquarium_00025.jpg
00802_Bla_Aquarium_00026.jpg
00802_Bla_Aquarium_00027.jpg
00802_Bla_Aquarium_00028.jpg <= this one
00802_Bla_Aquarium_00029.jpg

Como faço isso?

    
por aebersold 21.12.2012 / 11:17

7 respostas

12

Com o zsh, você pode fazer:

n=0; cp 00802_Bla_Aquarium_?????.jpg(^e:'((n++%4))':) /some/place

POSIXly, mesma ideia, só um pouco mais detalhada:

# put the file list in the positional parameters ($1, $2...).
# the files are sorted in alphanumeric order by the shell globbing
set -- 00802_Bla_Aquarium_?????.jpg

n=0
# loop through the files, increasing a counter at each iteration.
for i do
  # every 4th iteration, append the current file to the end of the list
  [ "$(($n % 4))" -eq 0 ] && set -- "$@" "$i"

  # and pop the current file from the head of the list
  shift
  n=$(($n + 1))
done

# now "$@" contains the files that have been appended.
cp -- "$@" /some/place

Como esses nomes de arquivo não contêm caracteres em branco ou curinga, você também pode fazer isso:

cp $(printf '%s\n' 00802_Bla_Aquarium_?????.jpg | awk 'NR%4 == 1') /some/place
    
por 21.12.2012 / 11:36
7

No bash, uma possibilidade engraçada, que funcionará bem aqui:

cp 00802_Bla_Aquarium_*{00..99..4}.jpg selected

Essa é definitivamente a resposta mais curta e mais eficiente: sem subshell, sem loop, sem pipe, sem awk processo externo; apenas uma bifurcação para cp (que você não pode evitar de qualquer maneira) e uma expansão de chave bash e glob (que você pode se livrar de completamente desde que você saiba quantos arquivos você tem).

    
por 21.12.2012 / 18:18
5

Simplesmente com o bash, você pode fazer:

n=0
for file in ./*.jpg; do
   test $n -eq 0 && cp "$file" selected/
   n=$((n+1))
   n=$((n%4))
done

O padrão ./*.jpg será substituído por uma lista de nomes de arquivos organizada em ordem alfabética, conforme declarado pelo homem bash, portanto, ele deve se adequar ao seu propósito.

    
por 21.12.2012 / 14:49
1

Se você sabe que não terá novas linhas em seus nomes de arquivos, poderá usar:

find . -maxdepth 1 -name "*.jpg" | sort | while IFS= read -r file; do
  cp "$file" selected/
  IFS= read -r; IFS= read -r; IFS= read -r
done
    
por 21.12.2012 / 14:58
0

Se você tiver ruby instalado, poderá usar o seguinte one-liner. Note que ele assume que o diretório selecionado existe.

ruby -rfileutils -e 'files = Dir.glob("*.jpg").each_slice(4) { |file| FileUtils.cp(file.first, "selected/" + file.first) }'

Ele pega uma lista de todos os arquivos com a extensão .jpg no diretório atual, divide-os em listas de quatro elementos e copia o primeiro elemento de cada lista para o diretório selecionado no diretório atual.

    
por 21.12.2012 / 12:12
0

Você pode usar um gerenciador de arquivos GUI e redimensionar a borda da janela até que cada 5 arquivos ocupem uma linha, e então usar o mouse para selecionar a primeira coluna ...

    
por 25.06.2018 / 19:49
-1

Olhando para stackoverflow.com/q/4553751/789593, que oferece uma solução para copiar cada segundo como @ N.N. mencionado, uma solução muito simples seria:

  • Remover o primeiro arquivo da pasta inicial
  • Copie todos os segundos da pasta inicial para uma pasta intermediária
  • Copie todos os segundos da pasta intermediária para a pasta final
  • Adicione o primeiro arquivo manualmente

Pode não ser muito eficiente, pois requer um passo extra de cópia. Isso deve ser muito fácil de fazer.

    
por 21.12.2012 / 11:45

Tags