Захват каждого 4-го файла

У меня есть 16 000 jpg из веб-граббера, которые я запускал в течение года, указывая на прошлый год. Я хочу найти способ получить каждое четвертое изображение, чтобы затем поместить их в другой каталог, чтобы позже превратить их в фильм. Есть ли простой скрипт bash или другой способ под Linux, которым я могу это сделать.

Они так называются......

кадр-44558.jpg

кадр-44559.jpg

кадр-44560.jpg

кадр-44561.jpg

Спасибо от новичка, нуждающегося в помощи.


Кажется, сработало. Пара ошибок в моем оригинальном посте. На самом деле было 280 000 изображений, и название было. /home/baldy/Desktop/webcamimages/webcam_2007-05-29_163405.jpg /home/baldy/Desktop/webcamimages/webcam_2007-05-29_163505.jpg /home/baldy/Desktop/webcamimages/webcam_2007-05-29_163605.jpg

Я побежал. cp $(ls | awk '{nr++; if (nr % 10 == 0) print $0}') ../newdirectory/

Который, кажется, скопировал изображения. 70-900 в день судя по всему.

Теперь я запускаю mencoder mf://*.jpg -mf w=640:h=480:fps=30:type=jpg -ovc lavc -lavcopts vcodec=msmpeg4v2 -nosound -o ../output-msmpeg4v2.avi

Я дам вам знать, как фильм работает.

ОБНОВЛЕНИЕ: Фильм не работает. В нем есть изображения только 2007 года, хотя в каталоге есть и 2008 год. webcam_2008-02-17_101403.jpg webcam_2008-03-27_192205.jpg webcam_2008-02-17_102403.jpg webcam_2008-03-27_193205.jpg webcam_2008-02-17_103403.jpg webcam_2008-03-27_194205.jpg webcam_2008-02-17_104403.jpg webcam_2008 -03-27_195205.jpg

Как я могу изменить свою строку менкодера, чтобы она использовала все изображения?


person user11950    schedule 16.09.2008    source источник


Ответы (8)


Один простой способ:

$ touch a b c d e f g h i j k l m n o p q r s t u v w x y z
$ mv $(ls | awk '{nr++; if (nr % 4 == 0) print $0}') destdir

person DustinB    schedule 16.09.2008
comment
Возможно, вам следует указать, что первая строка не нужна, она просто создает образцы данных... - person Sklivvz; 16.09.2008

Создайте скрипт move.sh, который содержит следующее:

#!/bin/sh
mv $4 ../newdirectory/

Сделайте его исполняемым, а затем сделайте это в папке:

ls *.jpg | xargs -n 4 ./move.sh

Это берет список имен файлов, передает четыре за раз в move.sh, который затем игнорирует первые три и перемещает четвертый в новую папку.

Это будет работать, даже если числа расположены не точно по порядку (например, если некоторые номера кадров отсутствуют, то использование арифметики по модулю 4 не сработает).

person Leigh Caldwell    schedule 16.09.2008
comment
лс *.jpg | xargs -n 10 ./copy.sh bash: /bin/ls: слишком длинный список аргументов cp: невозможно stat `0': нет такого файла или каталога - person user11950; 16.09.2008
comment
Я допустил ошибку. Было 280 000 изображений :) - person user11950; 16.09.2008

Как было предложено, вы должны использовать

seq -f 'frame-%g.jpg' 1 4 number-of-frames

для создания списка имен файлов, поскольку «ls» не будет работать с файлами размером 280 КБ. Таким образом, окончательное решение будет выглядеть примерно так:

for f in `seq -f 'frame-%g.jpg' 1 4 number-of-frames` ; do
  mv $f destdir/
done
person pjz    schedule 16.09.2008

seq -f 'frame-%g.jpg' 1 4 number-of-frames

… напечатает имена нужных вам файлов.

person Alexey Feldgendler    schedule 16.09.2008

Простой способ в perl (вероятно, легко адаптируемый к bash) состоит в том, чтобы объединить имена файлов в массив, затем получить порядковый номер и удалить те, которые не делятся на 4.

Что-то вроде этого напечатает нужные вам файлы:

ls -1 /path/to/files/ | perl -e 'while (<STDIN>) {($seq)=/(\d*)\.jpg$/; print $_ if $seq && $seq % 4 ==0}'

Вы можете заменить печать ходом...

Это будет работать, если файлы пронумерованы последовательно, даже если количество цифр не является постоянным, например, file_9.jpg, за которым следует file_10.jpg )

person Pat    schedule 16.09.2008

Учитывая предостережения масто о сортировке:

ls | sed -n '1~4 p' | xargs -i mv {} ../destdir/

Что мне нравится в этом решении, так это то, что все делает то, для чего оно было разработано, поэтому мне кажется, что оно unix.

person Iain    schedule 16.09.2008

Просто переберите список файлов:

files=( frame-*.jpg )
i=0
while [[ $i -lt ${#files} ]] ; do
  cur_file=${files[$i]}
  mungle_frame $cur_file
  i=$( expr $i + 4 )
done
person Community    schedule 16.09.2008
comment
Я не понял files=( frame-*.jpg ), что он делает? Я попробовал это в оболочке, и это дало мне только одно имя файла, назначенное переменной - person baxx; 27.08.2015

Это довольно дрянной, но это должно сделать работу. Предполагая, что вы в настоящее время находитесь в каталоге, содержащем все ваши файлы:

mkdir ../outdir
ls | sort -n | while read fname; do mv "$fname" ../outdir/; read; read; read; done

sort -n предполагает, что ваши имена файлов не имеют одинакового количества цифр; в противном случае ls будет сортироваться в лексическом порядке, где frame-123.jpg предшествует frame-4.jpg, и я не думаю, что это то, что вам нужно.

Пожалуйста, будьте осторожны, сделайте резервную копию своих файлов, прежде чем пробовать мое решение и т. д. Я не хочу нести ответственность за то, что вы потеряли данные за год.

Обратите внимание, что это решение обрабатывает файлы с пробелами в имени, в отличие от большинства других. Я знаю, что это не было частью примеров имен файлов, но легко написать команды оболочки, которые не обрабатывают пробелы безопасно, поэтому я хотел сделать это в этом примере.

person masto    schedule 16.09.2008