Я создаю видео таймлапса путем разделения видео на отдельные изображения, использования G'MIC через командную строку для усреднения каждых 7 кадров, затем произвожу результаты к новым изображениям, которые приведут к кадрам для таймлапса (этот способ, которым я получаю шумовое бесплатное видео, которое выглядит большим). Поскольку можно предположить, что у меня есть много кадров - несколько тысяч отдельных изображений в каталоге, названном последовательно (image1.tiff, image2.tiff, и т.д.). Я нашел сценарий, который работает отлично на перемещение файлов - однажды...
k=1; find source/ -type f | while read file; do
[[ k++ -le 7 ]] && mv "$file" target/
done
В чем я нуждаюсь, теперь должен сделать этот сценарий
Просто для уточнения каталог 1 должен содержать изображения 1-7, каталог 2 должен содержать изображения 8-14 и т.д.
Любая справка значительно ценится, я в значительной степени застреваю с этим.
(Python) сценарий ниже создает sub папки и организует Ваши файлы в папки:
Дополнительно:
, который принимает сценарий:
image1.tiff
, image2.tiff
и т.д. (никакие начальные нули). #!/usr/bin/env python3
import os
import math
import shutil
#---
directory = "/path/to/files" # path to your files
n_perfolder = 7 # number of files per sub folder
#--
# creating file list, extension
f_list = os.listdir(directory); ext = f_list[0].split(".")[-1]
# calculate number of folders
n_folders = math.ceil(len(f_list)/n_perfolder)
# creating folder names, including leading zeros
folders = [str(fn+1) for fn in range(n_folders)]
fl_names = [(len(max(folders, key=len))-len(fl))*"0"+fl for fl in folders]
# creating folders and allocate files
for i in range(len(fl_names)):
mkfolder = directory+"/"+fl_names[i]
if not os.path.exists(mkfolder):
os.makedirs(mkfolder)
r = range(i*n_perfolder+1, i*n_perfolder+n_perfolder+1)
for n in r:
try:
file = directory+"/"+"image"+str(n)+"."+ext
target = mkfolder+"/"+"image"+str(n)+"."+ext
shutil.copyfile(file, target)
except FileNotFoundError:
pass
Копия сценарий в пустой файл в главном разделе, установил каталог на Ваши файлы и количество файлов на подкаталог, сохраняет его как organize.py
.
Выполнение это командой:
python3 /path/to/organize.py
, Если Вы хотели бы к перемещение файлы вместо копирования, заменяет строку:
shutil.copyfile(file, target)
:
shutil.move(file, target)
(возражают против отступа!)
Можно использовать xargs (-n или - макс.-args) для определения номера файлов для перемещения, но иметь в виду, что аргументы ограничены ARG_MAX.
#!/bin/bash
images="./source/image*.tiff"
target="./target"
ls -v $images | xargs -n 7 | while read -a files; do mkdir $target/$((++n)) && mv -t $target/$n ${files[@]}; done
Если Вы не возражаете против того, чтобы это было перемещенным отдельно:
#! /bin/bash
for ((i = 1; ; i++))
do
mkdir -p target-$i
for j in $(seq $((i*7 - 6)) $((i*7)))
do
mv -t "target-$i" "source/image$j.tiff" || exit 1
done
done
Или, более краткий:
find source -type f -name 'image*.tiff' -print0 | \
sort -z --version-sort | \
xargs -0n7 bash -c 'TARGET=target-$((${1//[^0-9]/} / 7 + 1)); \
echo mkdir -p "$TARGET"; \
echo mv -t "$TARGET" "$@"' move-7
Объяснение:
-print0
печатает имена файлов, разделенные NUL (\0
) символ. Это - самый безопасный способ передать имена файлов как вывод к другим командам.sort
с -z
ищет nul-разграниченный вход, и вид версии позволяет нам безопасно числам переменной длины вида, так, чтобы image2.tiff
прибывает прежде image119.tiff
xargs
может ограничить количество аргументов, относился к каждой команде с -n
, таким образом, здесь мы используем -n7
. -0
для nul-разграниченного входа.$((${1//[^0-9]/} / 7 + 1))
- ${1//[^0-9]/}
удаляет все в аргументе, который не является числом. Целочисленное деление гарантирует, чтобы мы получили частное.mv
s требуемый.Осмотрите команды, произведенные, и если они смотрят хорошо, выполняют его снова после удаления echo
s.
KasiyA имеет интересную модификацию к этому.
Ответ JJOAO приносит rename
возражать. Во-первых, сделайте все каталоги:
FILES=(source/image*.tiff)
COUNT=${#FILES[@]}
DIR_NUM=$((COUNT / 7 + 1))
seq 1 $DIR_NUM | xargs bash -c 'mkdir -p "${@/#/target-}"'
rename -n 's;source/image(\d+)\.tiff$;"target-".int($1 / 7 - 1)."/image".$1.".tiff";e' source/image*.tiff
На самом деле мы могли применить первые четыре строки ко всем решениям здесь и пропустить повторное mkdir -p
.
sevenfile=0
newdir=1
for file in `ls -v /path/to/source/image*.tiff` ; do
mkdir -p "$newdir" && mv "$file" "$newdir"
[[ ++sevenfile -eq 7 ]] && sevenfile=0 && ((newdir++))
done
ls -v
команда сортирует файлы как естественный вид (версии) числа.ls
команда в этом Вашем случае, потому что все файлы конкретны и только image*.tiff
.mkdir -p $newdir
упаковывает каталог в ящики на основе newdir
переменная.
mv "$file" "$newdir"
перемещает файл в каталог который newdir
указывает.
sevenfile=0
обнулять, когда 7 файлов был перемещен ([[ ++sevenfile -eq 7 ]]
) и инкремент к newdir
значение.Обратите внимание на те изменения /path/to/source/
к Вашему фактическому исходному каталогу.
Если Вы не хотите анализировать ls
команда и если имя файлов включая пробелы, новые строки и и т.д.:
find /path/to/source/ -type f -name 'image*.tiff' -print0 | \
sort -z --version-sort | while IFS= read -d '' -r file; do \
mkdir -p "$newdir" && mv "$file" "$newdir" ;
[[ ++sevenfile -eq 7 ]] && sevenfile=0 && ((newdir++));
done
#!/usr/bin/perl
open(F,"-|","ls source/*") or die;
while(<F>){ chomp;
if(/(\d+).tiff/){
$dir= "target-" . (1+int($1/7));
mkdir($dir) unless -d $dir;
system "mv $_ $dir";
}
}