Как стать автором
Обновить

Комментарии 74

НЛО прилетело и опубликовало эту надпись здесь
Спасибо интересно было почитать :)

З.Ы. Неделя сортировки изображений по разрешению…
Ага, может быть тогда уже сделать отдельный пост «Сортировка по разрешению — на всех языках»:
— ссылки на различные реализации
— еще не задействованные ЯП и библиотеки
— сравнение по скорости
Интересно, это все-таки шутка или предложение было?
В каждой шутке есть доля предложения :) На самом деле я считаю Ваш способ наиболее удачным для объективного сравнения языков. Ибо обычно их сравнительный анализ сводится к демагогии сторон. А будь где-нибудь, когда-нибудь фолиант с большим количеством примеров на самых разных языках и с результатами сравнения этих примеров по некоторым объективным показателям (скорость, размер кода и т.п.), у нас был бы повод адекватно посмотреть на возможности, не опираясь на собственные привычки.
А я всего лишь хотел 7апа и инвайт на хабр о_О
Чорт, надо было запостить это сюда :)
Одного не понимаю, зачем сие чудо по умолчанию в установку ставить.
Зачем домохозяйке изощрятся в написании скриптов? Разве что расширить возможности зараженного «зомби».
Затем, что это не для домохозяйки. А скинуть скрипт за 300р и не просить его ставить Python уже можно. Постепенно Win становится дружелюбнее
Осталось только SSH добавить, и Win будет совсем дружелюбным.
Он есть — www.freesshd.com/ Я использую ежедневно. Конечно ощущение, что у велосипеда квадратные колеса, но все-же.
Есть кое что получше — WinRM, включается политиками.
Вообщ в Vista и 7 большая часть нового функционала именно для администраторов, а не для домохозяек. Им то и aero хватит :)
>>>dir $source -r -include *.jpg, *.png, *.gif | select FullName, @{Name=«Image»; Expression={New-Object
>>> System.Drawing.Bitmap $_.FullName}} -ErrorAction SilentlyContinue | where { $_.Image } | select FullName, >>>@{Name=«ImageFolder»; Expression={"{0}\{1}x{2}" -f $target, $_.Image.Width, $_.Image.Height}} | foreach {if (-not
>>> (test-path $_.ImageFolder)) {md $_.ImageFolder}; copy $_.FullName -destination $_.ImageFolder; $_}

может, все же наглядней было бы на Питоне? :)
Отдельно отмечу, что я буду намеренно немного усложнять реализацию, чтобы показать больше возможностей PowerShell. В реальных условиях что-то можно упростить, а от чего-то вообще избавиться.

Вы не путайте PIL конечно нагляднее, но я рад, что хоть какой-то стандартный Shell появился. Все эти {0} это .NET. Ждем вирусы :-)
там скрипты по-умолчанию untrusted вроде и сами не запускается по дабл-клику, надо хорошо попросить
Эт шутк был. RDP вот тоже есть, но все используют VNC/RКто-то-там И это обидно. Хочется чтоб Юзер мог скинуть URL по Jabber и я увидел его экран.

Я так понимаю, надо скрипт запустить типа PWShell script.pws? Или Окошко выскакивает постоянно «Вы нажали на кнопку?»
1. При даблклике на скрипте он открывается блокнотом.
2. Запуск скриптов по умолчанию запрещен. Чтобы включить надо выполнить особую команду под администратором. Чтобы узнать команду — надо взглянуть на хелпу — супер фильтр :)
1. Есть удаленный помощник. Не URL правда нужно скидывать, а файлик. Но десктоп Юзера вы в итоге увидете.

2. То, что вы не пользуетесь RDP не значит что им не пользуются. RDP в разы быстрее и удобнее того же VNC. Особенно на медленных соединениях. Позволяет прицеплять локальные принтеры, диски и т.п. В новой версии обещали поддержку DirectX.
Ну, это не мой мир; у меня баш да питон из коробки :)
Все еще не понимаю Вашего сарказма. В моем мире Jscript, VBscript, а теперь еще и PowerShell «из коробки». И если питон еще может потягаться с ними по удобству, то баш просто откровенно сливает.
А чего вы взяли, что я саркастичен? Нет, в вашем мире тоже появился шелл, и это очень мило, пятнадцать-то лет спустя…
В «нашем мире» уже 20 лет есть и шелл и скриптинг. Просто Вы о них, похоже, не знаете.
Ну про скриптинг на VB я много хорошего слышал и видел много потрясающих специалистов по сборке формочек. Про шелл… Это вы про batch-файлы и cmd.exe? И вы это серьезно?
гуглите про Windows scripting Host, доступно аж для win98 и примерно с тех времен, позволяет писать скрипты из 'каропки' на JS и VB.В скриптах доступно использование объектов ActiveX (а это значит доступно все, от баз данных доинтернета, хотя графический интерфейс как то не замечал), при очень вдумчивом изучении документации MSDN можно очень неплохо автоматизировать работу администратора и не только.
хотя графический интерфейс как то не замечал

Обычно использовались HTA (HTML Applications).
Потрясающе все таки, как некоторые линуксоиды умеют с надменным видом нести чушь. Начиная с того, что спутав VB и VBS Вы показали, что вообще не понимаете о чем речь и заканчивая тем, что bash таки есть в винде, просто он слишком убог для скриптинга, а в качестве шелла вполне сгодится и cmd (тем более, что все те утилиты, с которыми баш просто отвратно выглядит, но без которых он беспомощнее ребенка, тоже есть на винде — POSIX сертификация есть, как никак).
Вы попросту предвзяты. Сравниваете one-liner с 52-строчником (ну на питоне в общем то one-liner-ы и невозможны). Хотите читаемости — перепишите то же самое так:
Copy Source | Copy HTML
  1. [void][reflection.assembly]::LoadWithPartialName("System.Windows.Forms")
  2.  
  3. $source = "x:\source"
  4. $target = "x:\target"
  5.  
  6. foreach ($file in dir $source -r -inc *.jpg, *.gif, *.png) {
  7.     try {
  8.         $image = new-object System.Drawing.Bitmap $file.FullName
  9.         $targetdir = "{0}\{1}x{2}" -f $target, $image.Width, $image.Height
  10.         if (!(test-path $targetdir)) {
  11.             md $targetdir
  12.         }
  13.         copy $file $targetdir
  14.  
  15.         Write-Host $file -> $targetdir
  16.     } catch {
  17.         Write-Host $file " **IS NOT COPIED**"
  18.     }
  19. }
  20.  

Вы действительно считаете, что питоновский вариант читабельней? Но с другой стороны, лично я б вместо перекладывания файлов по каталогам, взял бы Wia.ImageFile и проставил нужные теги
добавьте это в статью, а то будет еще пару десятков коментариев о том какой же ужасный однострочник…
Статья не моя — я просто вступился на правах мимопроходил-а
Побольше бы таких мимопроходцев :)
Да я не сравниваю, просто говорю, что one-liner выглядел убого, ничем не лучше оригинальных perl`измов.

Все же, согласитесь, это просто еще один Шелл, только с очень большим опозданием.
> Да я не сравниваю, просто говорю, что one-liner выглядел убого, ничем не лучше оригинальных perl`измов.

А Вы попробуйте ради интереса написать тоже самое на баше в виде пайпа. Уверяю, хитросплетения всяких grep/awk оставит те же самые впечатления у людей непосвященных в таинство действия.

> Все же, согласитесь, это просто еще один Шелл, только с очень большим опозданием.

Тогда можно было бы сказать, что питон — просто еще один язык, только с очень большим опозданием. Но это не совсем так. И python и powershell несут нам немало новых возможностей.
Объектные пайпы это очень круто, конечно (без всякой иронии), просто данный конкретный пример не слишком удачный. Вот помнится классический пример из «Unix Hater's Handbook» (вывести рекурсивно все файлы с расширением *.el, которые не имеют соответствующего им *.elc в том же каталоге) решается очень даже наглядно. Более того, формат вывода остается в точности таким же как и у простого dir.

И, да
sort(find((dir /b folder1\*.txt && dir /b folder2\*.txt), «text»))

Оно бы выглядело не так :-)
Пример однозначно в статью, спасибо)
> (dir /b folder1\*.txt && dir /b folder2\*.txt) | find «text» | sort
>…
> В функциональных языках программирования это могло бы выглядеть так:
> sort(find((dir /b folder1\*.txt && dir /b folder2\*.txt), «text»))

но скорее вот так:
(dir /b folder1\*.txt && dir /b folder2\*.txt) |> find «text» |> sort
ближе к оригиналу :)
> ближе к оригиналу

Это, если не секрет, к какому оригиналу ближе? :) Потому как у меня в уме была больше классика ФП в виде LISP и скобочки, скобочки, еще больше скобочек :)
имелось ввиду к пайповому оригиналу :)

вот этому: "(dir /b folder1\*.txt && dir /b folder2\*.txt) | find «text» | sort"
осталось написать сортовку на Jscript-е и bash-е и тогда все будут довольны и «неделя сортировки изображений» закончится… у вас всего 3 дня, товарищи!
Jscript как то так:
Copy Source | Copy HTML
  1. var Source = "x:\\source";
  2. var Target = "x:\\target";
  3.  
  4. var Fso = new ActiveXObject("scripting.FileSystemObject");
  5. var Image = new ActiveXObject("Wia.ImageFile");
  6.  
  7. function foreach(Collection, Proc) {
  8.     for (var enumerator = new Enumerator(Collection); !enumerator.atEnd(); enumerator.moveNext())
  9.         Proc(enumerator.item());
  10. }
  11.  
  12. function SortImages(Folder) {
  13.     foreach(Folder.Files, function (file) {
  14.         try {
  15.             Image.LoadFile(file);
  16.             var targetPath = Target + "\\" + Image.Width + "x" + Image.Height + "\\";
  17.             if (!Fso.FolderExists(targetPath)) {
  18.                 Fso.CreateFolder(targetPath);
  19.             }
  20.             Fso.CopyFile(file, targetPath);
  21.             WSH.Echo(file + " -> " + targetPath);
  22.         } catch (e) {
  23.             WSH.Echo(file + " **WAS NOT COPIED**");
  24.         }
  25.     });
  26.     foreach(Folder.SubFolders, SortImages);
  27. }
  28.  
  29. SortImages(Fso.GetFolder(Source));
  30.  
PowerShell не нравится, какая-то ацкая смесь перла, тикля и бейсика. Нафига? Уж лучше б MS JSсript command-line сделали, всяко удобнее и проще. Ну да ладно, я все равно python-way предпочитаю =)
За статью однако-же спасибо.
Вы не поверите, но Jscript скриптинг был в Windows начиная эдак винды с 98-й.
Перечитайте внимательнее мой комментарий. Там написано русским по белому «JSсript command-line».
Я имел в виду Jscript shell, как например в Firebug. Про cscript и wscript я, разумеется, в курсе, писал несколько утилит. Кстати, имею доложить, что он (jscript) тормоз тот еще, существенно уступает тому же python по скорости.
По поводу скорости целиком поддерживаю, хотя как язык он весьма интересен. Функциональный, динамический. От таких скорости обычно не ждешь, но можешь ожидать интересных решений :) Что до Jscript, то в основе PS лежат достаточно строгие CLS-языки, которые становясь частью интерактивного действа были вынуждены обрасти всякой синтаксической мишурой. Я боюсь, что будь на его Jscript, он выглядел бы не лучше :)
>Я боюсь, что будь на его Jscript, он выглядел бы не лучше :)

Придерживайся MS стандартов всё было бы ок. ECMAscript еще никто не отменял. А так, Вы, возможно, правы.
А в чем Jscript не соответствует ECMA-262? Мне, право, интересно. Да и не имеет ECMAscript никакого представления, что такое stdin/stdout, так что для пайпов его не так просто использовать.
Да хотя бы вот
javascript.ru/blog/Dmitry-A.-Soshnikov/Tonkosti-ECMA-262-3.-CHast-5.-Funkcii.
(Ctrl-F -> Реализация ECMAscript от Microsoft – Jscript, встроенная в Internet Explorer, на текущий момент (вплоть до версии Jscript 5.8 – IE8) имеет ряд багов)

Ну и пресловутое

Wscript.echo([1,].length)

>cscript /nologo 1.js
2

Вообще нюансов много. Но я скорее не о том, а о хорошо известном подходе MS, который в вольном пересказе звучит так: «Если мы видим как улучшить стандарт, мы не колеблясь делаем это». Но ведь стандарты для того и есть чтоб им следовать, хороши они или нет. Ярким проявлением этой философии был механизм рендеринга блочной модели страницы браузера, который в IE кардинально отличался от стандарта, ну и так далее. Оттуда и пляски с режимами совместимости и т.д.
Большое спасибо за информацию, буду вникать. Что до нюансов, то они мне напоминают тезисы из справочника юного холиварщика)) Честно скажу, мне совершенно не интересен подход MS, их моральный облик и данные финансовой отчетности) Для меня это данность, а вот бороться с ней как раз и поможет та информация, которой Вы меня вооружили :)
а так уж важны пайпы эти самые? в питон-шеле их как-то нет, и в firebug шеле — нет, и ничего вроде. А так получается что и пайпы есть, т.е. удобно писать one-liners, и ООП с классами и прочими вкусностями есть — соизволь использовать, а в сумме что? Правильно — те самые монструозные one-liner-коды которые мы имели честь созерцать в сообщении уважаемого автора.

Предвосхищая реплики «Больше фич хороших и разных», «Не хочешь — не используй» и т.д. вежливо не соглашусь и сошлюсь на сверх-гибкий и приспособленный по сути для тех же целей Perl, о поддержке и возможности прочтения кода через месяц после написания которого уже ходят легенды.
да это обычный .NET язык с пайпами, оформленный в традициях шеллов. никакого перла и Basic-а, см выше про сравнение однострочника с многострочниками.
>никакого перла

$_ и вообще префиксование переменных $, всякие @ и прочий синтаксический шум…
В шеллах этого «префиксирования» навалом, включая cmd.exe. Даже в SQL его можно найти. Тогда можно сказать, что это смесь шелла, SQL, C# :)
я не возражаю )

p.s. в python и ruby шелле, как не сложно было бы догадаться, префиксования нет )
Согласитесь, что ieval('_.basename()… — это не верх синтаксического совершенства )
ну вот опять, люди судят о языке/подходе основываясь на 1, далеко не лучшем примере применения.
Ценность данного сообщения была бы стократ выше, будь в нем второй, гораздо более лучший «пример применения»)) Я, увы, так устроен, что оперирую фактической информацией и руководствуюсь презумпцией качественности приводимых примеров, пока не доказано обратное. Поэтому у меня пока нет оснований считать, что пример pawnhearts в чем-то хуже другого, которого я пока не видел)
Ёлка-палка, а Вы видели вообще самое первое сообщение с которого пошел весь сыр-бор с сортировкой картинок по размерам? там как-раз python-код.
Мало того, что видел, а еще и подробно описал в посте отличие подходов, поэтому сравнение некорректно. Если бы стояла задача сравнить эти два кода, то я бы просто написал простой императивный скрипт на c# и вопрос «префиксования» не стоял бы в принципе, не находите?
ух блин… сорри, проглядел ники…
Короче я лишь хочу сказать, что проведенное Вами сравнение оказалось (на мой глубоко субъективный взгляд) не в пользу PowerShell. И вообще я не рекомендовал бы его использовать только потому что он стоит в системе по умолчанию, примерно так же как и с IE. Да, IE открывает сайты, то FF (Chrome/Opera) то лучше… так и здесь. Ну хоть 1 аргумент использовать PS кроме того, что ставится по дефолту?
вариант на bash
for f in $(find ./ -type f |xargs -n1 file |grep image |awk -F':' '{print $1}' |xargs -n1 gm identify); do path=$(echo $f|awk '{print $3}'); mkdir $path >/dev/null; cp $f $path; done
вместо awk '{print $3}' можно использовать cut -d' ' -f3
поясление на всякий случай find ./ -type f рекурсивно находит все файлы в текущем каталоге и подкаталогах, xargs -n1 file — применить к каждому команду file которая выводит имя файла: тип файла, grep image отфильтровать только те строки, в которых тип содержит слово image, далее избавляется от типа файла, оставляем только снова имена, применяем к каждому gm identify которая выводит информацию об изображении, с помощью конструкции for f in $(command); do ...;done для каждой строки из результата делаем последовательность команд. сначала вырезаем колонку с информацией о размере изображения и записываем в переменную path; создаем каталог path(если он уже создан — оно ругнется, поэтому мы перенаправляем ругань в /dev/null, там опечатка, должно быть mkdir $path 2>/dev/null (чтобы не выводить сообщения об ошибках), дальше тоже опечатка, должно быть cp $(echo $f |awk '{print $1}') $path; — копируем первую колонку(пуль к файлу) в $path
что хорошо в bash так это короткие имена команд, наследие телепайтов, плохо в powershell — очень длинные имена классов из .net(в visualstudio от этого должно как-то спасать автодополнение, а в powershell?).
по поводу объектной ориентированности, к примеру gm identify -verbose filename
выводит:
Image: cole-gerst-blog.jpg
Format: JPEG (Joint Photographic Experts Group JFIF format)
Geometry: 576x360
Class: DirectClass
Type: true color
Depth: 8 bits-per-pixel component
и т.д.
чем не объект? далее мы просто вырезаем интересующую строчку gm identify -verbose cole-gerst-blog.jpg |grep Geometry|cut -d: -f2
Большое спасибо за хороший пример с пояснением.

плохо в powershell — очень длинные имена классов из .net(в visualstudio от этого должно как-то спасать автодополнение, а в powershell?)

Для автодополнения можно использовать PowerTab. Ну а длинные имена классов и прочий функционал надо постепенно заворачивать в скриптлеты или конвертеры. Как, например, в PowerShell Community Extensions есть Import-Bitmap вместо моих сложных конструкций с инстанцированием System.Drawing.Bitmap. Или как по аналогии с выражением [xml]"?<root><item>item 1</item></root>" можно сделать конвертер [image]. Имхо, проблема PS в том, что он пока не накопил достаточного количества «синтаксического сахара», чтобы обернуть все те возможности, что есть в .NET FCL.

чем не объект? далее мы просто вырезаем интересующую строчку gm identify -verbose cole-gerst-blog.jpg |grep Geometry|cut -d: -f2

Может тем, что я не могу делать так: $file.Directory.GetAccessControl().SetAuditRule(...) или так:

Copy Source | Copy HTML
  1. ls *.jpg | foreach {
  2.     $image = new-object System.Drawing.Bitmap $_.FullName;
  3.     $graphic = [System.Drawing.Graphics]::FromImage($image);
  4.     $graphic.DrawLine(...);
  5.     $graphic.FillPolygon(...);
  6.     $graphic.DrawString(...);
  7.     $image.Save(...)
  8. }

Все-таки полноценные объекты и их текстовая сериализация (которая далеко не всегда и далеко не везде) — это не совсем одно и то же.
>чем не объект?

Прежде всего тем, что допускает ошибки. Что, если в EXIF встречается слово Geometry? Что, если используемая версия GraphicsMagick выводит geometry (с маленькой буквы) вместо Geometry?
grep -i geometry\:
но особенность GraphicsMagick в том что они не меняют параметры и их вывод от версии к версии, отличие от imagemagick основное — в стабильности api, только-добавляют новые
Я даже не знаю за что я больше люблю башевые однострочники (да и скрипты надо сказать ненамного лучше) — то ли за то, что их без поллитры не расшифруешь, то ли за то что они никогда не работают.
Вы там ниже задавали вопрос: а чем текст — не объект. Вот пара тест кейсов для Вашего решения:


Пара очевиднейших примеров и я вижу уже как минимум три ошибки.
в моем примере было gm identify -verbose, а не gm identify
gm identify test\ invalid.jpg |grep Geometry будет иметь errorlevel >0 и не выдаст ничего
т.е. в скрипте мы пишем
geo=$(gm identify test\ invalid.jpg |grep Geometry\:) && next_action
next_action выполниться только если errorlevel у grep == 0
в моем примере было gm identify -verbose, а не gm identify

Нет, что ж я слепой что ли? Написано ж прямым текстом:
xargs -n1 gm identify


И этого
&& next_action
тоже нет

Что же до verbose — файлы таки могут содержать символ перевода строки в имени — все опять сломалось. В целом сериализация/десериализация в raw-text работает довольно плохо. Нужно хотя бы внимательно эскейпить спец символы, чем никто не занимается.
а вот ещё пример на питоне:
from ipipe import *
import Image
for name,img in iwalk(dirs=False) | ieval('_.basename(),Image.open(_)',errors='drop'):
  img.resize((img.size[0]/2,img.size[1]/2)).save('/tmp/'+name)
Хороший пример (я не шучу — действительно клевый), вот только он делает совершенно не то, что пример из поста.
from ipipe import *
import Image, os, shutil
for img in iwalk(dirs=False) | ieval(Image.open, errors='drop'):
  path = '%dx%d' % img.size
  if not os.path.exists(path): os.makedirs(path)
  shutil.copyfile(img.filename, path)

как вариант:
from ipipe import *
import gtk, os, shutil
for f,img in filter(iwalk(dirs=False) | ieval('_,gtk.gdk.pixbuf_get_file_info(_)'):
  path = '%dx%d' % (img[1],img[2])
  if not os.path.exists(path): os.makedirs(path)
  shutil.copyfile(f, path)
второй вариант неправильный, правильно:
from ipipe import *
import gtk, os, shutil
for f,img in iwalk(dirs=False) | ieval('_,gtk.gdk.pixbuf_get_file_info(_)'):
  if img:
    path = '%dx%d' % (img[1],img[2])
    if not os.path.exists(path): os.makedirs(path)
    shutil.copyfile(f, path)
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Изменить настройки темы

Истории