Как проще сделать несколько тысяч кусков похожих текстов?

AlekseyI

Я к компам и железу имею отношение только в качестве жмущего кнопки, что там внутри и как это работает не ведаю вовсе Так что извиняйте за ламерство.
Вопрос следующий.
Для SPSS в конторе постоянно пишется море однотипных синтаксисов следующего рода:
TABLES MISSING = INCLUDE
/BASE = QUALIFIED
/FORMAT = ZERO
/GBASE=CASES
/MRGROUP=MR '' q1.1 to q1.21
/FTOTAL = ВЫБОРКА
/PTOTAL = ВСЕГО
/TABLE = (MR) + ВЫБОРКА BY ВСЕГО + city
/SORT = MR
/TITLE = 'Заголовок'
/CAPTION = 'name'
/STATISTICS =
CASES (ВЫБОРКА ' ')
cspсt (MR (pct5.1) 'процент' : city).
Вот представьте себе, что таких кусков текста нужно сделать несколько сотен, а иногда и тысяч. Изменяемые поля: q1.1 to q1.21 и city. Задолбал рабский труд. Как бы это дело можно было бы автоматизировать?
Спасибо!

Ivan8209

> Задолбал рабский труд. Как бы это дело можно было бы автоматизировать?
Прочитать про текстовые препроцессоры.
Например, про m4.
---
"Аллах не ведёт людей неверных."

Ivan8209

И про make, если ещё не.
---
"Аллах не ведёт людей неверных."

Helga87

если у тебя встречается много подобных задач, как вариант решения — заботать любой из языков программирования. Фактически, для твоей задачи надо уметь сделать формочку с тремя полями, уметь считать строку из файла, заменить в строке q1.1, q1.21 и city на их значения, получившуюся строку записать в файл.
если только эта задача, то попроси кого-нибудь за пиво/сок написать.

kokoc88

> Задолбал рабский труд. Как бы это дело можно было бы автоматизировать?
Прочитать про текстовые препроцессоры.
Как новенькому в этом разделе, сразу же дам тебе совет. Кохтпу не слушай - он просто тупой безмозглый мозгоёб.

enochka1145

Кстати, интересно, на каком языке это лучше (в широком смысле) сделать?
Я бы выбрал Perl.

Helga87

я бы сказал, что для новичка перл — не самый лучший выбор. Скорее лучше выбрать Java/C#/VB.net/Python/ ruby. Они понятнее

Ivan8209


changequote({,})dnl
dnl
dnl $1 -> q1.1 to q1.21
define(XXX,{
TABLES MISSING = INCLUDE
/BASE = QUALIFIED
/FORMAT = ZERO
/GBASE=CASES
/MRGROUP=MR '' $1
/FTOTAL = ВЫБОРКА
/PTOTAL = ВСЕГО
/TABLE = (MR) + ВЫБОРКА BY ВСЕГО + $2
/SORT = MR
/TITLE = 'Заголовок'
/CAPTION = 'name'
/STATISTICS =
CASES (ВЫБОРКА ' ')
cspсt (MR (pct5.1) 'процент' : $2).
})dnl
dnl
XXX(qX1 to qY1, cityZ1)
XXX(qX2 to qY2, cityZ2)



TABLES MISSING = INCLUDE
/BASE = QUALIFIED
/FORMAT = ZERO
/GBASE=CASES
/MRGROUP=MR '' qX1 to qY1
/FTOTAL = ВЫБОРКА
/PTOTAL = ВСЕГО
/TABLE = (MR) + ВЫБОРКА BY ВСЕГО + cityZ1
/SORT = MR
/TITLE = 'Заголовок'
/CAPTION = 'name'
/STATISTICS =
CASES (ВЫБОРКА ' ')
cspсt (MR (pct5.1) 'процент' : cityZ1).


TABLES MISSING = INCLUDE
/BASE = QUALIFIED
/FORMAT = ZERO
/GBASE=CASES
/MRGROUP=MR '' qX2 to qY2
/FTOTAL = ВЫБОРКА
/PTOTAL = ВСЕГО
/TABLE = (MR) + ВЫБОРКА BY ВСЕГО + cityZ2
/SORT = MR
/TITLE = 'Заголовок'
/CAPTION = 'name'
/STATISTICS =
CASES (ВЫБОРКА ' ')
cspсt (MR (pct5.1) 'процент' : cityZ2).


Минутное дело.
---
"Аллах не ведёт людей неверных."

tamusyav

Еще один из вариантов - использовать слияние в Word.

Ober

XXX(qX1 to qY1, cityZ1) 
XXX(qX2 to qY2, cityZ2)

На мой взгляд, всё это "XXX(..., ...)" можно опустить и сделать фильтр (например, на том же Awk или, OMFG!, Python) из вот такого мусора:
qX1 to qY1, cityZ1
qX2 to qY2, cityZ2
qX3 to qY3, cityZ3

или такого:
qX1 to qY1
cityZ1

qX2 to qY2
cityZ2

qX3 to qY3
cityZ3


в то, что надо.
А вообще, пусть тредстартер напишет поподробнее, что ему надо

Ivan8209

Фильтр --- это неудобно.
Даже если все куски однородны.
---
...Я работаю антинаучным аферистом...

sakura

+1 за Perl
Изменяемые поля: q1.1 to q1.21 и city.
Привет!
Если ты сделаешь табличку (ну, скажем, в Ecxel'е состоящую из двух столбцов - q1.1 to q1.21 и city, то я сгенерю тебе столько таких кусков, сколько будет строк в твоей таблице. Также выложу текст скрипта, чтобы ты мог им впоследствии пользоваться.
Можешь прислать табилчку мне по почте: belozersky.msu.ru
Вопрос: эти куски должны быть в одном файле или же для каждого куска должен быть отдельный файл?
Если в отдельных файлах, то какие у них должны быть имена и расширения?
Если в одном файле, то как отделять один кусок от другого? Просто пустой строкой пойдет?

Werdna

Еще один из вариантов - использовать слияние в Word.
Виндузятнеги жгут!
там где обычную перлячку можно написать за 2 минуты...

Ivan8209

Перловцы тоже жгут: в таких задачах фильтры _очень_ неудобны.
---
...Я работаю антинаучным аферистом...

tamusyav

Там им достаточно одной Без установки перла. Не говоря уже о том, что изучение слияния занимает меньше времени, чем изучение перла

AlekseyI

Спасибо всем!
я конечно не все тут просек (особенно, что делать с тем, что после code: - куда совать гы но тем неменее!
Вот же головы то

Ivan8209

> Но в более сложной задаче (например, с более сложными правилами преобразования)
> использование макропроцессора будет уместно,
> а вот ad hoc решение в виде фильтра может поиметь моск еще на этапе разработки,
> если вообще будет укладываться в концепцию фильтра
Я тебе сразу говорю, что оно не укладывается в фильтр.
И даже объясню, почему. В таких задачах куски почти всегда неоднородны.
Соответственно, тебе надо будет эти неоднородности как-то учитывать: либо
склеивать файлы из кусков, либо придумывать какую-то разметку.
В последнем случае, ты приходишь к тому же текстовому препроцессору,
но написанному к случаю и вручную.
---
...Я работаю антинаучным аферистом...

Ivan8209

> Вот я и прошу пояснить, что это за класс задач.
> И где в задаче автора треда присутствует неоднородность кусков?
Скорее всего (включаю телепатию там производится анализ данных, итоги которого потом
отображаются на куче графиков. Повторяющиеся куски соответствуют точкам, но там есть
или могут быть точки другого рода, описание осей и других свойств графика, команды
отображения графика. Вот так и наберётся несколько неоднородных кусков.
Если пролог и эпилог фиксированы, их ещё можно приклеивать из других файлов,
а вот если они меняются, начинается кошмар. Ну, может быть, не кошмар, но неудобно.
---
...Я работаю антинаучным аферистом...

sakura

Я решил эту задачу с помощью HTML::Template
#!/usr/bin/perl -w

use strict;
use warnings;

##################################################################
# Antonov Ivan ver.1.00
#
#--- 2007Jan17 ---
# ver.1.00
#

$| = 1; # Turn off buffering

use HTML::Template;
use Data::Dumper;

##################################################################
# CONSTANTS
my $secondary_vals = ['city', 'oblast', 'distr'];

###################################################################
# Parse input data
die usage if @ARGV!=1;

############
my $START_TIME = time;

run(
fn => $ARGV[0],
);

warn "\nElapsed time: ".(time-$START_TIME)." sec.\n";
############

###################################################################
# SUBROUTINES
sub run
{
my %opts = @_;

open(F, $opts{fn}) or die "Can't open file '$opts{fn}': $!";

# omit header
$_ = <F>;

my $data = [];
while(<F>)
{
next if /^\s*$/;

s/[\n\r]+$//;

my($question_var, $sort_mode, $question, @tail) = split /\t/;

die "Wrong string '$'" if !defined $question_var || !defined $sort_mode || !defined $question || @tail;

my $content = [];
foreach my $scnd_val (@$secondary_vals)
{
push(@$content,
{
secondary => $scnd_val,
question => $question,
question_var => $question_var,
is_sort => $sort_mode eq 'sorted' ? 1 : 0
}
);
}

push(@$data,
{
header => "*********** $question.",
content => $content
}
);
}

close F;


############## OUTPUT ############

my $tp = new HTML::Template(filename => 'spss_template.txt');

$tp->param(data => $data);

print $tp->output;
};

sub usage
{
my($script) = $0 =~ /([^\\\/]+)$/;
return"
DESCRIPTION:

USAGE:
$script data.txt

OPTIONS:

";
}

Вот файл spss_template.txt:
<TMPL_LOOP NAME='data'><TMPL_VAR NAME='header'>
<TMPL_LOOP NAME='content'>
TABLES MISSING = INCLUDE
/BASE = QUALIFIED
/FORMAT = ZERO
/GBASE=CASES
/MRGROUP=MR '' <TMPL_VAR NAME='question_var'>
/FTOTAL = ВЫБОРКА
/PTOTAL = ВСЕГО
/TABLE = (MR) + ВЫБОРКА BY ВСЕГО + <TMPL_VAR NAME='secondary'>
/TITLE = 'Заголовок'
/CAPTION = '<TMPL_VAR NAME="question">'
/STATISTICS =
CASES (ВЫБОРКА ' ')
cspсt (MR (pct5.1) 'процент' : <TMPL_VAR NAME='secondary'>)
<TMPL_IF NAME='is_sort'> /SORT = MR
</TMPL_IF>.

</TMPL_LOOP>
</TMPL_LOOP>

Вот кусочек входного файла (tab-delimited):
Имя переменной вопроса	Сортировка	Метка (Формулировка вопроса)
age1 unsorted вопрос age1
q001 to q001.21 unsorted вопрос q001
q002 unsorted вопрос q002
q003 unsorted вопрос q003
q004 unsorted вопрос q004
q005 unsorted вопрос q005
q006 unsorted вопрос q006
q007 unsorted вопрос q007
q008 unsorted вопрос q008
q009 unsorted вопрос q009
q010 unsorted вопрос q010
q011 unsorted вопрос q011
q012 unsorted вопрос q012
q013 sorted вопрос q013

Вот результат:

*********** вопрос age1.

TABLES MISSING = INCLUDE
/BASE = QUALIFIED
/FORMAT = ZERO
/GBASE=CASES
/MRGROUP=MR '' age1
/FTOTAL = ВЫБОРКА
/PTOTAL = ВСЕГО
/TABLE = (MR) + ВЫБОРКА BY ВСЕГО + city
/TITLE = 'Заголовок'
/CAPTION = 'вопрос age1'
/STATISTICS =
CASES (ВЫБОРКА ' ')
cspсt (MR (pct5.1) 'процент' : city)
.


TABLES MISSING = INCLUDE
/BASE = QUALIFIED
/FORMAT = ZERO
/GBASE=CASES
/MRGROUP=MR '' age1
/FTOTAL = ВЫБОРКА
/PTOTAL = ВСЕГО
/TABLE = (MR) + ВЫБОРКА BY ВСЕГО + oblast
/TITLE = 'Заголовок'
/CAPTION = 'вопрос age1'
/STATISTICS =
CASES (ВЫБОРКА ' ')
cspсt (MR (pct5.1) 'процент' : oblast)
.


TABLES MISSING = INCLUDE
/BASE = QUALIFIED
/FORMAT = ZERO
/GBASE=CASES
/MRGROUP=MR '' age1
/FTOTAL = ВЫБОРКА
/PTOTAL = ВСЕГО
/TABLE = (MR) + ВЫБОРКА BY ВСЕГО + distr
/TITLE = 'Заголовок'
/CAPTION = 'вопрос age1'
/STATISTICS =
CASES (ВЫБОРКА ' ')
cspсt (MR (pct5.1) 'процент' : distr)
.


*********** вопрос q001.

TABLES MISSING = INCLUDE
/BASE = QUALIFIED
/FORMAT = ZERO
/GBASE=CASES
/MRGROUP=MR '' q001 to q001.21
/FTOTAL = ВЫБОРКА
/PTOTAL = ВСЕГО
/TABLE = (MR) + ВЫБОРКА BY ВСЕГО + city
/TITLE = 'Заголовок'
/CAPTION = 'вопрос q001'
/STATISTICS =
CASES (ВЫБОРКА ' ')
cspсt (MR (pct5.1) 'процент' : city)
.


TABLES MISSING = INCLUDE
/BASE = QUALIFIED
/FORMAT = ZERO
/GBASE=CASES
/MRGROUP=MR '' q001 to q001.21
/FTOTAL = ВЫБОРКА
/PTOTAL = ВСЕГО
/TABLE = (MR) + ВЫБОРКА BY ВСЕГО + oblast
/TITLE = 'Заголовок'
/CAPTION = 'вопрос q001'
/STATISTICS =
CASES (ВЫБОРКА ' ')
cspсt (MR (pct5.1) 'процент' : oblast)
.


TABLES MISSING = INCLUDE
/BASE = QUALIFIED
/FORMAT = ZERO
/GBASE=CASES
/MRGROUP=MR '' q001 to q001.21
/FTOTAL = ВЫБОРКА
/PTOTAL = ВСЕГО
/TABLE = (MR) + ВЫБОРКА BY ВСЕГО + distr
/TITLE = 'Заголовок'
/CAPTION = 'вопрос q001'
/STATISTICS =
CASES (ВЫБОРКА ' ')
cspсt (MR (pct5.1) 'процент' : distr)
.

...

Ivan8209

УЖАС!
Прогони свой скрипт через wc, ощути разницу.
Мы вот тут говорим про расширяемость и изменяемость решения, подумай, что делать,
если понадобится вставлять прологи, эпилоги и какие-нибудь разделители,
если понадобится использовать другие шаблоны, особенно --- той же арности.
Будешь приписывать переключение состояний?
---
"Narrowness of experience leads to narrowness of imagination."

sakura

зато быстро и дешево...

Ivan8209

> зато быстро
Ты только набивал дольше, чем я делал всё вместе.
> и дешево...
В каком смысле?
В смысле установки? Два моих файла против кучи твоих, ибо кроме интерпретатора надо ворох библиотек.
В смысле написания решения? См. выше.
В смысле гибкости? См. ещё выше.
В смысле времени выполнения? Неизвестно. Да и не важно.
Где ты увидел это "дёшево"? Только в том, что ты знаешь перл, но не м4?
---
"Narrowness of experience leads to narrowness of imagination."

sakura

Честно говоря, m4 я не знаю...
А про то, что эту задачу можно сделать другим (может быть более простым способом) я и не спорю. Мне на написание этой вещи потребовалось 20 мин. Если ты сделал то же самое за 5 - молодец! Я твою программу и не осуждал.
Вот все, что я могу сказать...

laki

чето у меня подозрение что на шарпе кода будет в 2а 3и раза меньше

AlekseyI

Ребят, спасибо за внимение к теме и обсуждение!
Даже не ожидал, что кто-то вообще откликнется.
Для себя, например, понял, что лучше всего perl, т.к. человек мне РЕАЛЬНО помог Хотя я пока и не понимаю, как мне поставить HTML::Template и адаптировать этот скрипт для таких же аналогичных задач в будущем.
Кстати в ворде таки получилось тоже слиянием сделать (но, думаю, зная perl это удобнее и эффективнее делать на perl (или другими средствами программирования, чем в word)
Еще раз спасибо!

qsk78

Хотя я пока и не понимаю, как мне поставить HTML::Template
У тебя, видимо, стоит Windows и ActiveState Perl. Если так, то подключись к интернету, открой ppm (Perl Package Manager) и набери
install HTML::Template

Ivan8209

> адаптировать этот скрипт для таких же аналогичных задач в будущем.
Поставь m4, и будет тебе счастье.
См. самый первый пример, я запускал это прямо в редакторе: M-| m4,---
но можно и через командную строку: m4 первый > второй
Требуется установить только два файла (или даже один, если есть статическая сборка
шаблоны делаются очевидно, если возникнут вопросы, подскажем.
---
"Vyroba umelych lidi, slecno, je tovarni tajemstvi."

sakura

Хотя я пока и не понимаю, как мне поставить HTML::Template
Ставь его отсюда: HTML::Template, Там и документация есть, что это такое и как этим пользоваться.
Оставить комментарий
Имя или ник:
Комментарий: