LINUX.ORG.RU

Wget-дамп сайта + множественные переименования


0

1

Имеем ресурс в виде фотосайта с защитой от дураков - картинки недоступны по прямым адресам и качаются только по РНР-скрипту ссылкой следующего вида:
[.../get.php]+[имя картинки]+[2 каких-то уникальных параметра]
Картинки сливаются по списку от конвееа «wget html | grep»
Задача состоит в том, что количество сливаемых файлов заранее неизвестна вообще, и всю полученную кучу нужно переименовать так, чтобы каждый файл имел именем дату и время своего создания (не локально, а с сервера). Если это никак невозможно, то требуется переименование в номера по порядку закачки, при том по такой маске:
000X.jpg..XXXX.jpg - чтобы небыло лишних нолей и прочего мусора.

Так как первый вариант я не смог решить, то переименовывал так:
:: Получаем число одним порядком большее, чем количество файлов в каталоге и одновременно кратное 10-ти:
a () { echo ${#} ; } ; d=1 ; while (( `a \`ls . | tr " " «_»\`` > d )) ; do d=$((d*10)) ; done
:: Меняем имена одинм циклом:
for i in `ls (по дате и времени)` ; do mv '$i' ${d:1}.jpg && ((d++)); done
Но функция a () для ls с результатом более 10 000 выполняется невероятно долго и тяжко, а rename ведёт себя ещё хуже - 8 часов висел, потом я нажал ^C...

★★

Последнее исправление: zzdnx (всего исправлений: 1)
num=$(find . -maxdepth 1 -type f | awk 'END{print length(NR)}')
i=0
find . -maxdepth 1 -type f | while read f; do ((i++)); mv -v "$f" $(printf "%0${n}d.jpg" $i); done
AITap ★★★★★
()
Ответ на: комментарий от AITap

Поправка

Вместо find ... поставьте ls -1t

И вообще, подобные задачи лучше решать на Perl (use LWP) или любом другом чуть более «продвинутом» языке программирования.

AITap ★★★★★
()
Ответ на: Поправка от AITap

Перл просто не люблю, так как не понимаю. Аналогично AWK.
Немного не понял наличие $i в конструкции $(printf «%0${n}d.jpg» $i)

И вообще - есть-ли способ слить файлы с оригинальной датой???

zzdnx ★★
() автор топика
Ответ на: комментарий от zzdnx

Аналогично AWK.

Перевести?

Немного не понял наличие $i в конструкции $(printf «%0${n}d.jpg» $i)

Напечатать число $i (номер файла) в виде числа длиной $n разрядов (дополненного нулями слева при необходимости) и с ".jpg" на конце.

И вообще - есть-ли способ слить файлы с оригинальной датой???

Просто с датой? Скачайте его wget'ом, и, если сервер передаёт дату, она будет сохранена в его метаданных.

Пример программы на Perl, скачивающей якобы картинки по ссылкам с данного URL по данному шаблону в файлы с именами из заголовка Last-Modified:

#!/usr/bin/perl

use warnings;
use strict;

use LWP::UserAgent;

my $linklist = "http://linux.org.ru/";
my $leftjoin = "http://www.linux.org.ru/";

my $ua = new LWP::UserAgent;
$ua->agent('Mozilla/5.0 (compatible)');

my $r1 = $ua->get($linklist);
die $ARGV[0].": ".$r1->status_line."\n" unless $r1->is_success;

my ($rpic, $name);
for ($r1->decoded_content =~ m#(/news/[^/]+/[0-9]+)"#g) {
	# FIXME: нужен правильный шаблон ^^^
#	print "$_\n"; next;
	print "$_ ";
	$rpic = $ua->get($leftjoin.$_);
	print $rpic->status_line."\n" and next unless $rpic->is_success;
	print "no date set\n" and next unless $name = $rpic->header('Last-Modified');
	$name .= "_" while -f $name.".jpg";
	$name .= ".jpg";
	open PIC,">:bytes",$name || die "couldn't open ".$name." for writing: $!\n";
	print PIC $rpic->content;
	close PIC || die "Failed to close file descriptor: $!\n";
	print "$name\n";
}

AITap ★★★★★
()
Ответ на: комментарий от zzdnx

И есть-ли способ быстрого и простого переименования в дату-время?

rename 's/(.*)(\.[^.]+)/(localtime((stat($1.$2))[9])).$2/e' *

Переименует файлы в (время модификации).(расширение)

AITap ★★★★★
()
Ответ на: комментарий от AITap

Очень трудно понимать язык, которого почти не знаешь, но за скрипты спасибо. Попробуем с другой стороны:

Имеем фал, набитый такими строками (вырезка из html):

<div style=«text-align:center»><div><img src="./mods/misc/getfile.php?name=test4.jpg&wcu=201012270217393800886&modnum=199973128" id=«images0»" style=«display:none; border:1px solid „onmouseover=„this.style.border='1px solid '„onmouseout=„this.style.border='1px solid '„onload=„resizeImage(this)“/></div><div class=„clear“></div><br /></div>

Задача - слить файлы по списку, попутно задавая имена в виде даты-времени. Как можно реализовать такую задачу штатными средствами?
./mods/misc/getfile.php я могу заменить полным путём через sed.

zzdnx ★★
() автор топика
Ответ на: комментарий от zzdnx

Curl считается штатным средством? Тогда что-то вроде:

sed ... | while read url
do
 date=$(curl -sI "$url" | sed -rn '/^Last-Modified:/{s/^Last-Modified: //p;q}')
 curl -O "${date}.jpg" "$url"
done

AITap ★★★★★
()
Ответ на: комментарий от zzdnx

curl: Remote file name has no length!
curl: try 'curl --help' or 'curl --manual' for more information
^C

zzdnx ★★
() автор топика
Ответ на: комментарий от zzdnx

Переменная date остаётся пустая, и если в конце добавить «> 1.jpg», то терминал спокойно записывает указанный файл

zzdnx ★★
() автор топика
Ответ на: комментарий от zzdnx

Извиняюсь, ошибочно поставил "-O" вместо "-o". Правильно будет вот так: curl -o «${date}.jpg» «$url».

Что печатает команда curl -sI «$url»?

AITap ★★★★★
()
Ответ на: комментарий от zzdnx

Дата съёмки: 2011:12:18 07:34:50 - это написано в метеданных, но их не все программы оставляют, и не все устройства вписывают... Думаю, что Last-Modified более доступный вариант, который имеется всегда.

zzdnx ★★
() автор топика
Ответ на: комментарий от AITap

curl -sI «$url»
HTTP/1.1 200 OK
Date: Wed, 21 Dec 2011 21:24:11 GMT
Server: Apache/2.2.8 (Unix) mod_ssl/2.2.8 OpenSSL/0.9.8e-fips-rhel5 PHP/5.2.5
X-Powered-By: PHP/5.2.5
Set-Cookie: PHPSESSID=f6cb4956e097ede8fc06da3129347a63; path=/
Expires: Mon, 1 Jan 2000 00:00:00 GMT
Cache-Control: private
Pragma: private
Content-Disposition: attachment; filename=«6b3d0153[1]-s.jpg»
Accept-Ranges: bytes
Content-Length: 277393
Content-Type: application/octet-stream

zzdnx ★★
() автор топика
Ответ на: комментарий от zzdnx

Вывод: сервер не возвращает дату модификации файла. Если нигде на странице она отдельно не указана, получить её невозможно.

AITap ★★★★★
()
Ответ на: комментарий от AITap

Значит, придётся именовать порядковыми цифрами. Спасибо большое за помощь.

zzdnx ★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.