· Начало · Статистика · WASM.RU · Noir.Ru ·

 WASM Phorum (Оффлайн - 24.11.2003) —› WASM.HEAP —› Требуется текстовый редактор...

. 1 . 2 . >>

Посл.отвђт Сообщенiе


Дата: Авг 17, 2003 08:31:39

Необходимо большой текстовый файл *.txt разбить на мелкие
текстовые файлы, разбиение должно быть не размерным, а
смысловым, т.е. каждый файл должен содержать только
определённую часть текста большого файла.
Подскажите каким текстовым редактором это можно сделать.
Если это может Word то подскажите как?


Дата: Авг 17, 2003 19:33:52

Наверное всё-таки нет такого soft'а...

Тогда как бы организовать такой script на perl, чтобы
при построчном копировании он искал определённую строку
в файле(разделитель), при достижении которой копирование бы
перенаправлялось в следующий файл, опять до достижения такой
строки-разделителя, и так последовательно до конца файла.
Вот скрипт, который последовательно построчно копирует текстовые
файлы, но как организовать описанное выше я не знаю, может есть
у кого мысли по этому поводу:
-----------------------------------------------------------------------------------
#!/usr/bin/perl -w
$symbol="_";
foreach $f (<*.txt>)
{
open(IN, "$f") or die "Can't open file: $!";
chop($f);
chop($f);
chop($f);
chop($f);
open(OUT, "+>$f$symbol.txt") or die "Can't open file $f$symbol.txt for writing: $!";

while(<IN>)
{
	print OUT;
}

close(OUT);
close(IN);
}

---------------------------------------------------------------------- -------------


Дата: Авг 17, 2003 21:54:52 · Поправил: KiNDeR

Asterix
А на паскале не подойдет?...
label
metka;
const
n=128;
var
f_name:text;
fn: array[1..n] of text;
countI:integer;
str1,fnt:string;
_ch_:char;
BEGIN
     countI:=1;
     Assign(f_name,'test.txt');
     reset(f_name);
metka:
     str(countI,str1);
     fnt:='test'+str1+'.txt';
     assign(fn[countI],fnt);
     rewrite(fn[countI]);
     while not eof(f_name) do
      Begin
       read(f_name,_ch_);
       if _ch_<>'_' then write(fn[countI],_ch_)
        else
         Begin
          close(fn[countI]);
          inc(countI);
          goto metka;
         End;
      End;
END.


Дата: Авг 18, 2003 00:09:09

KiNDeR

Может и подойдёт, но мне нечем это скомпилить и я не понимаю
смысл твоего кода ;-)


Дата: Авг 18, 2003 04:01:19 · Поправил: Fixer

Asterix
Можешь воспользоваться следующей программкой на C
// txtpick.c
//
// Приложение для разделения одного большого файла на много маленьких
//
// При запуске приложения в коммандной строке необходимо ввести имя обрабатываемого файла.
// Выходные файлы будут иметь имена:
//
// <имя_входного_модуля>XXX.<его_расширение>
//
// где XXX сквозная нумерация модулей начиная с 0.

#include <stdio.h>
#include <malloc.h>
#include <string.h>

// Разделитель по которому будет распознаваться окончание модуля
#define SEPARATOR_SYMBOL "{$THE END$}"
#define BUFER_SIZE 1024

unsigned int  outCount = 0;
unsigned int  numberModul = 0;
char separatorString[] = SEPARATOR_SYMBOL;

// Формируем имя выходного файла
int getNameOutFile(const char* nameIn, unsigned int numberModule, char* nameOut)
{
  int Ret = 1;
  char*  strPath = strdup(nameIn);

  if (strPath)
  {
    char* strExt = strPath + strlen(strPath);
    char* pdest = strrchr(strPath, '.');
    int pos = 0;

    if (pdest)
    {
      pos = pdest - strPath;
      if (((pdest = strrchr(strPath, '\\')) == 0) ||
          ((pdest - strPath) < pos))
      {
        strPath[pos] = 0;
        strExt = strPath + pos + 1;
      }
    }

    sprintf(nameOut, "%s%03u.%s", strPath, numberModule, strExt);
    free(strPath);
  }
  else Ret = 0;

  return Ret;
}

// Перенос информации из файла источника в файл назначения и поиск разделительной
// последовательности символов
//
// Выход:
// 0 - достигнут конец файла источника
// 1 - необходимо создать дополнительный текстовый модуль
int moveData(FILE* sourceFile, FILE* descinationFile)
{
  int Ret = 3;
  int checkChar = 0;
  int lengthSeparatorString = strlen(separatorString);
  char readChar;

  while(Ret == 3)
  {
    readChar = fgetc(sourceFile);

    if (feof(sourceFile)) Ret = 0;
    else
      if (separatorString[checkChar] == readChar)
      {
        if (++checkChar >= lengthSeparatorString)
        {
          Ret = 1;
          checkChar = 0;
          break;
        }
      }
      else fputc(readChar, descinationFile);
  }

  if ((Ret == 0) && checkChar) fwrite(separatorString, 1, checkChar, descinationFile);

  return Ret;
}

FILE* createTxtModul(const char* sourceName)
{
  char nameModule[256];
  getNameOutFile(sourceName, numberModul++, nameModule);
  FILE* f = fopen(nameModule, "wt");

  if (!f) printf("Can't open output file: %s\n", nameModule);
  else printf("** Create output file: %s\n", nameModule);

  return f;
}

int main(int argc, char* argv[])
{
  if (argc == 2)
  {
    FILE* fileIn = fopen(argv[1], "rt");
    FILE* fileOut = NULL;

    if (fileIn)
    {
      while((fileOut = createTxtModul(argv[1])) && moveData(fileIn, fileOut)) fclose(fileOut);
      if (fileOut) fclose(fileOut);
    }
    else printf("Can't open input file: %s\n", argv[1]);
  }
  else printf("Undefined command\n");

  return 0;
}


Дата: Авг 18, 2003 05:31:38 · Поправил: KiNDeR

Asterix
Получает файл из командной строки
label
metka;
const
n=128;
var
f_name:text;
fn:text;
countI:integer;
str1,fnt:string;
_ch_:char;
BEGIN
     countI:=1;
     Assign(f_name,ParamStr(1));                {Откроем файл из командной строки}
     reset(f_name);
metka:
     str(countI,str1);                          {Сформеруем имя выходного файла}
     fnt:='test'+str1+'.txt';

     assign(fn,fnt);                            {Создадим его}
     rewrite(fn);

     while not eof(f_name) do                   {Пока не конец болшого файла}
      Begin
       read(f_name,_ch_);                       {Читаем его по-символьно}
       if _ch_<>'_' then write(fn,_ch_)         {Если это не "_", то пишем в файл}
	else                                    {иначе}
	 begin
	  close(fn);                            {сохраним выходной файл}
	  inc(countI);
	  goto metka;
	 end;
      End;
END.


Дата: Авг 18, 2003 10:10:07

Fixer
KiNDeR

Спасибо.
Но в данный момент у меня даже C нет, поэтому воспользоваться пока
не могу, но потом обязательно проверю...


Дата: Авг 18, 2003 19:47:30

Asterix

Здорово! Как ты там?
По твоему вопросу - такой софт есть. Вордом он называется :) Все зависит только от того, по какому критерию ты хочешь разбивать куски текста. Большинство народу забывает, что ворд имеет VBA, а VBA, хоть и васик, но умеет много.
Определи мне параметр разбиения (а то слово "по смыслу" меня пугает, может тебе ИИ нужен :)), а я тебе его или на перле забецаю, или на VBA. Что пожелаешь.
Да, и еще. Неча тут адресом exetools бросаться! А то порвешь ресурс, раздавая его направо-налево и мне будет грусно :(


Дата: Авг 18, 2003 20:19:16

volodya

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

p.s. всё, про exetools молчу, но разве это поможет :-)


Дата: Авг 18, 2003 21:48:01

Asterix

ОК. Только не понятно, почему разделитель должен быть уникальным. Скажем, алгоритм может выглядеть где-то так:

примем разделитель равным ****** - такое в тексте не встретится (как ты его шарашишь в файл - я не знаю)

условимся считать файл одной большой строкой;
читаем эту строку в массив, считая ****** разделителем блоков (при этом поинтер скользит по файлу);
блок прочитан? записать его в файл с именем $i.tmp.txt;
увеличить $i;
и пошла душа в рай до EOF.

Хочешь конечный вариант на перле?


Дата: Авг 18, 2003 22:37:44

[ volodya: Хочешь конечный вариант на перле?]

Хочу. Но в тексте может быть ********, например как разделитель
текста, ну типа как ############ в исходниках, поэтому уж лучше какая-нить
уникальная строка, причём она будет содержать только ключевую фразу,
а всё остальное пробелы, вплоть до \n.


Дата: Авг 18, 2003 23:23:22 · Поправил: volodya

Хочу

А я не дам :)
Вместо этого лови очередной трюк перла.
Итак, когда файл читается с использованием <> оператора, то читается одна строка. Почему? Да потому что переменная $/ инициализирована значением \n по умолчанию! Следовательно, если ты хочешь, чтобы в роли разделителя выступала последовательность ******, то просто сделай
$/ = "******";
(только лучше local $/, дабы для дальнейших вычислений $/ не испортить!).
И все. Читай свой файл, используя любой уникальный разделитель.


Дата: Авг 18, 2003 23:27:03 · Поправил: volodya

Где-то так:
open(IN, "t.txt") or die "Can't open file: $!";

$i = 1;
$/ = "******";

while(<IN>)
{
	open(OUT, "+>$i.$tmp.txt");
	print OUT;	
	close(OUT);
	$i++;
}

close(IN);


Дата: Авг 19, 2003 00:37:57

Спасибо! Работает!
Ещё бы сделать так чтоб строка разделитель не попадала в файл и было
бы вообще здорово...


Дата: Авг 19, 2003 00:46:39 · Поправил: volodya

Ну вот, лентяй.
chomp тебе на что? Она тоже $/ использует!

Да, у меня здесь книга, в которой полный список таких переменных. Тебе бы не помешала!

. 1 . 2 . >>


Powered by miniBB 1.6 © 2001-2002
Время загрузки страницы (сек.): 0.077