KDJ, simple and useful, but it'll take 2*charcount*sizeof(widechar) of RAM during execution if I get things right. May be found out too hard for the system
Andrey_A_A wrote:В алелпаде большинство написано на js, а к нему привыкнуть и понять надо...
Прошу прощения, если дополнение покажется излишним (с учетом ответа от KDJ) но вдруг тема еще не исчерпана.
1) Отличия JS от VBS не так и велики - надо только точку с запятой в конце строки ставить (шутка). JS требует чуть больше внимательности, т.к. он регистрозависимый.
2) Оговорюсь, что мой "пример" пригоден для обработки НЕюникодных файлов. Но если это не проблема, то здесь можно обойтись вообще без AkelPad.
Я попробую показать, как "пользователь" "пользователю" (где "пользователь" = непрограммист с остаточными знаниями по школьной информатике и при наличии справки), как решить задачу путем "рассуждений":
Вариант 1. "наглядный".
Он вытекает из следующей посылки "а что если сделать все строки одинаковой длины и свести задачу сортировки к тривиальной?". Для этого нужно выровнять строки по длине, отсортировать, и затем вернуть строки к первоначальному виду (до выравнивания).
1) Исходный файл читается дважды. При первом чтении выясняется максимальная длина строки в файле.
2) Читаем файл повторно и генерируем выходной файл, в котором каждая строка (взятая из исходного файла) дополняется спереди пробелами до длины максимальной строки - получаем этакую огромную прямоугольную "простыню" с текстом выравненным по правому краю.
Внимание! Есть опасность того, что генерируемый файл окажется очень большого размера (если исходный файл содержит очень много коротких строк и очень длинную максимальную строку). Т.е. на входе имеем файл, размер которого - сумма длин его строк, а на выходе -файл, размер которого - произведение длины максимальной строки на количество строк.
3) Сортируем сгенерированный файл.
Получаем что-то вроде
4) Отсекаем лидирующие пробелы (прижимаем текст к левой границе).
Внимание! Если исходный файл содержит значимые пробелы в начале строк, то они также будут потеряны. Чтобы этого не происходило, можно предварительно добавлять в начало каждой строки некий символ-маркер (например '#') и только затем пробелы. При отсечке же удалять пробелы до маркера и сам маркер.
Подход примитивный и затратный. Много минусов. Один плюс - наглядный (как мне кажется). Собственно, только ради этого он и приведен.
Взгляните на картинку с "отсортированным файлом". Начальные пробелы являются просто частью ключа сортировки. Очевидное неудобство - эта часть разной длины. ЭТО плюс слово "ключ" и подводит нас к варианту номер два. Вариант 2.
Можно улучшить предыдущий вариант и избавиться от его недостатков, сделав его не только менее ресурсоемким но и более простым в кодировании, если совместить с использованным ранее (при сортировке по длине строк) методом (универсальность). Для этого нужно доработать фрагмент кода
А именно, преобразовывать числа в строки ФИКСИРОВАННОЙ ширины (1 -> '00000001', 2654 -> '00002654', ...). Тогда Вы получите возможность сортировки такой, какой хотели.
while (!file_in.atEndOfStream)
{
TXT = file_in.ReadLine();
TXT_SIZE = TXT.length; // получить длину строки
TXT_SIZE = TXT_SIZE.toString(10); // получить строковое представление числа в 10-тичной системе
// дополнить нулями слева до восьми** символов ('123' --> '00000123').
while (TXT_SIZE.length < 8)
{
TXT_SIZE = '0' + TXT_SIZE;
}
// записать в генерируемый файл
file_out.WriteLine(TXT_SIZE + '\t' + TXT);
}
// **Примечание: 8 выбрано для удобства, как число, обычно равное, либо кратное размеру табуляции,
// а не для обработки строк до 100 миллионов символов ;)
Здесь уже можно остановиться и подумать "а можно ли не загружать файл в AkelPad для сортировки?".
Чтобы избавиться от необходимости загружать полученный файл в редактор, сортировать его и затем выделять и отрезАть левый блок с ключами, Вы можете передоверить и всю эту работу скрипту.
Так, сортировку НЕюникодного файла можно поручить системной утилите SORT (см. справку по командной строке в Windows).
Если предполагается наличие в файле строк длиннее 4096, то с параметром "/rec символы" примерно так:
SORT /rec 65535 d:\WORK\notes_NUM.txt /o d:\WORK\notes_NUM_SORT.txt
для обратного порядка, с ключом "/r":
SORT /r /rec 65535 d:\WORK\notes_NUM.txt /o d:\WORK\notes_NUM_SORT.txt
Запуск же самой команды, см. справку Windows Script Host по методам RUN или EXEC.
var WshShell = WScript.CreateObject ("WScript.shell");
// запуск в скрытом окне командной строки, и выполнение сортировки с ожиданием завершения ее работы.
WshShell.run ('cmd.exe /c "SORT /rec 65535 d:\\WORK\\notes_NUM.txt /o d:\\WORK\\notes_NUM_SORT.txt"', 0, "TRUE");
// собщение о выполнении сортировки (само закроется через 5 секунд)
WshShell.Popup ("Сортировка завершена. Создан отсортированный файл.", 5,"Сообщение от скрипта",0);
(для JS не забывайте "удваивать слеши" в путях и "закавычивать строки").
Для удаления в отсортированном файле колонки с ключами подойдет метод substr (для JScript, а для VBScript функция Right)
stringvar.substr(start [, length ])
"Выкусываем" 8 символов ключа + 1 символ табулятора.
Поскольку отсчет индексов ведется с нуля, то стартовая позиция (одна и та же) = 9, а раз нужен весь "хвост" строки, то второй параметр опускаем.
Таким образом TXT.substr(9) даст то, что нужно.
Кусок кода записи в файл:
TXT = file_in.ReadLine();
file_out.WriteLine(TXT.substr(9));
Это все. Осталось только собрать все вместе и добавить, если хотите, интерактивности (чтобы не модифицировать скрипт всякий раз, когда меняется имя файла или потребуется изменить порядок сортировки). А также предусмотреть обработку промежуточных файлов. Итоговый скрипт будет никак не привязан к AkelPad, что тоже неплохо. P.S.
Не за чем "невротизировать себя недостижимой целью". Стремление к изучению хороших скриптов похвально - я от этих слов не отказываюсь и не вкладываю в них никакого сарказма, только это не годится для "первых шагов". Стремясь сделать с первого раза "идеально", можно вообще никогда не начать (всегда будет казаться, что нужно "еще что-нибудь почитать"). Начните с примитивных и корявых решений. Это лучше чем ничего.
Оценивая же итоговые затраты, берусь утверждать, что для самостоятельного написания первого СВОЕГО скрипта ТАКОГО уровня, Вам потребуется не более 2-3 дней на ознакомление с JS либо VBS и еще пол-дня на собственно работу по "программированию" и тестированию. Для скриптов уровня KDJ трех недель не достаточно.
Спасибо, всё шикарно работает, добавил
var nResult=AkelPad.Call("Format::LineRemoveDuplicates");
перед AkelPad.SetSel(0, -1);
теперь сразу удаляет дубликаты и сортирует!!!
Andrey_A_A wrote:...добавил
var nResult=AkelPad.Call("Format::LineRemoveDuplicates");
перед AkelPad.SetSel(0, -1);
AkelPad.Call(Format::LineRemoveDuplicates") should be placed after AkelPad.SetSel(0, -1);
This will ensure, that the removal of duplicates and sorting is performed on the same range. In this case, the entire text.
I have a question.
How do I sort of regard for local alphabet, in a script?
For example, normal sort gives the result: ć > z.
And it should be: c < ć < d < z
Infocatcher wrote:Для функций, работающих со строками, напрашивается обобщающий диалог с кнопками и галочкой «Учитывать регистр символов».
...
А скрипт делать лень.
But it's all in Format plugin.
You can do it yourself in ContexMenu plugin.