2013-04-10 2 views
2

У меня возникли проблемы с анализом CSV из текстового файла, и мне было интересно, могли бы вы, ребята, помочь мне. До сих пор у меня есть следующее:REXX - Parse from CSV File

Файл CSV (DATA.txt) выглядит примерно так: в нем всегда будет 15 полей, разделенных запятой. Не все поля являются обязательными, поэтому некоторые из них будут заполнены, а некоторые - пустыми.

Seattle,Lastname,Firstname,DOB,SEX,etc,etc 
Seattle,Lastname,Firstname,DOB,,etc,etc 
Portland,Lastname,Firstname,DOB,SEX,,,etc 
Portland,Lastname,Firstname,DOB,SEX,etc,etc 

А вот мой REXX код

SOURCEFILE = "C:\DATA\DATA.TXT" 
IF A=2 THEN DO COUNTER=1 TO LINES(SOURCEFILE) 
    PARSE VALUE LINEIN(SOURCEFILE) WITH CITY "," LAST_NAME "," FIRST_NAME "," MOM_NAME "," MIDDLE_NAME "," DAD_NAME "," DOB "," etc "," etc "," etc "," etc "," SEX "," etc "," etc 
    CALL SETCURSOR 4,23 
    CALL CREATEDATA 
END 

CREATEDATA: 
CALL TYPE CITY 
CALL PRESS TAB 
CALL TYPE LAST_NAME 
CALL PRESS TAB 
CALL TYPE DATE(U) 
CALL PRESS TAB 
CALL TYPE FIRST_NAME 
CALL PRESS TAB 
CALL PRESS ENTER 
RETURN 

Я не уверен, если я должен использовать ARG или УАК при разборе, или если я правильно написал первые две строки. Я знаю, что моя функция CREATEDATA работает правильно, потому что я получаю «CITY», но не анализируемое значение. Любая помощь будет очень высоко ценится. Спасибо!

ответ

1

Несколько комментариев:

1) Lines(SourceFile) в системе Windows, вероятно, включает в себя чтение всего файла для подсчета числа CR-LF последовательности. Затем ваш цикл Parse value LineIn(SourceFile) читает его снова. Типичный Rexx способ сделать это было бы:

Address SYSTEM 'TYPE' SourceFile with output stem Lines. 
Do Counter = 1 to Lines.0 
    Parse var Lines.Counter ... 
End 
Drop Lines. 

По крайней мере, до тех пор, пока файл не настолько велико, что держать его в массиве является дорогостоящим в памяти.

2) Вы течете в CreateData в конце своей петли, поэтому вы видите «ГОРОД». Вам понадобится Return или Exit после этого инструкции End.

3) В свете № 2 очевидно, что Parse никогда не выполняется, поскольку City неинициализирован (значение неинициализированной переменной в Rexx - это его имя в верхнем регистре). Это обусловлено A=2, чего не должно быть.

+0

Согласно книге Коулислава Rexx, встроенная функция LINES может возвращать количество строк в файле, на который делается ссылка, или, если это невозможно определить, значение «1», где значение ненулевого счета будет соответствовать в противном случае - «0». Я использую ooRexx на окнах совсем немного и могу подтвердить, что ooRexx не считает все строки, он просто возвращает 0/1. Я использую следующее для чтения файлов по одной строке за раз: DO WHILE LINES (filename)> 0; PARINE VALUE LINEIN (имя файла) с ...; END – NealB

+0

Результат 'Lines()' зависит от реализации. Некоторые реализации возвращают счет, другие - только 1 или 0, как вы заметили. Именно поэтому я предпочитаю загружать стебель: 'Lines.0' является фактическим счетом. –

1

один вопрос, что является целью, если А = 2, то в

IF A=2 THEN DO COUNTER=1 TO LINES(SOURCEFILE) 

если A! = 2 петля пропущена. Я подозреваю, что ваша программа должна быть:

SOURCEFILE = "C:\DATA\DATA.TXT" 
DO COUNTER=1 TO LINES(SOURCEFILE) 
    PARSE VALUE LINEIN(SOURCEFILE) WITH CITY "," LAST_NAME "," FIRST_NAME "," MOM_NAME "," MIDDLE_NAME "," DAD_NAME "," DOB "," etc "," etc "," etc "," etc "," SEX "," etc "," etc 
    CALL SETCURSOR 4,23 
    CALL CREATEDATA 
END 

RETURN /* prevent the fall through to createdata */ 

CREATEDATA: 




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

разбора оператор имеет следующий базовый формат

синтаксического анализа [источник] [синтаксический-контроль]

где [источник] icludes

ARG - аргументы при вызове процедуры pull - данные сняты со стека var - данные поступают из переменной value ...с данными поставки встраиваемого

Так что ваш синтаксический анализ может быть сделано как

linein = LINEIN(SOURCEFILE) 
    PARSE var linein CITY "," LAST_NAME "," FIRST_NAME "," MOM_NAME "," MIDDLE_NAME "," DAD_NAME "," DOB "," etc "," etc "," etc "," etc "," SEX "," etc "," etc 

или

DO COUNTER=1 TO LINES(SOURCEFILE) 
     CALL SETCURSOR 4,23 
     CALL CREATEDATA LINEIN(SOURCEFILE) 
    END 

    RETURN /* prevent the fall through to createdata */ 

    CREATEDATA: 
    parse arg CITY "," LAST_NAME "," FIRST_NAME "," MOM_NAME "," MIDDLE_NAME "," DAD_NAME "," DOB "," etc "," etc "," etc "," etc "," SEX "," etc "," etc 

Наконец попка росс сказал, что вы должны попробовать и Aviod линии (ИСХ), поскольку она включает в себя чтение всего файла