Чтение нескольких строк текстовых данных в одну запись - PullRequest
0 голосов
/ 04 апреля 2020

Я видел очень похожие проблемы с моими, но не мог понять, в чем моя проблема. Я пытаюсь прочитать в текстовом файле с разделителями трубы, где некоторые записи в две строки, как показано ниже. Переменные: ID, O CC, DESCRIPTION, V1-V19, где V1-V19 разные переменные. Когда я запускаю код без V1-V19, он работает как чудо, но затем, когда добавляю их к нему, даже «тест», чтобы увидеть, если следующая строка - цифра c или не работает.

Вот мой код,

data sample;

infile myfile  dlm='|' dsd  end=endin ;
length schedule $12 desc $300;
input @1 schedule $ occ $ desc $  v1-v15 $ v16 $ v17-v19;
input @@;
test= notdigit(substrn(left(_infile_),1,1));
If test then do;
  desc=catx(' ',desc,_infile_);
  input;
end;
run;

и вот набор тестовых данных,

9450007|23023|Reporter||33100|||||1|||||||||D||49|1
9451007|23023|Reporter||43086||||||1||||||||E||50|1
9462034|11021|Manager 
Oversee all operations, report to board of director|||||||||12|||||||F||1|12
9460034|43061|Office Assistant
Schedule client appointments, enter visit|||||10|||||||||||B||3|10
9451002|24011|Engineer, Market Exempt||86353||||||||1||||||G||28|1
9450002|12021|Market President/Chief Revenue
Officer||135000||||||||||1||||I||29|1 
9460027|11111|Mgr, Emergency Care||131248||||||||||1||||I||208|1

Ответы [ 2 ]

0 голосов
/ 06 апреля 2020

Для надежно разграниченных данных, которые, к сожалению, разбиты на значения или разделители данных, частичные строки могут быть объединены в оставшуюся строку. Если в удерживаемой строке содержится ожидаемое количество разделителей (21 |), удерживаемая строка может быть перенесена обратно во входной буфер, а затем из нее может быть прочитан оператор input.

Пример:

* create data file for example code;

filename the_data temp;

data _null_;
file the_data;
input;
put _infile_;
datalines;
9450007|23023|Reporter||33100|||||1|||||||||D||49|1
9451007|23023|Reporter||43086||||||1||||||||E||50|1
9462034|11021|Manager 
Oversee all operations, report to board of director|||||||||12|||||||F||1|12
9460034|43061|Office Assistant
Schedule client appointments, enter visit|||||10|||||||||||B||3|10
9451002|24011|Engineer, Market Exempt||86353||||||||1||||||G||28|1
9450002|12021|Market President/Chief Revenue
Officer||135000||||||||||1||||I||29|1 
9460027|11111|Mgr, Emergency Care||131248||||||||||1||||I||208|1
;

* manipulate _infile_ associated with external file in order to
* use input statement for data line, and field, split over multiple lines;

data want;
  length schedule $12 occ $8 desc $300;
  length v1-v16 $8 v17-v19 8;
  length heldline $256;

  infile the_data dlm='|' dsd missover;

  * read data file line into input buffer and _infile_;
  input @;

  if missing(heldline) then 
    /* first line or data from prior 'data' was output */
    /* copy the input buffer to a retained variable (in case the 'data' is split/incomplete) */
    heldline = _infile_;      
  else
    /* heal the split */
    heldline = catx (' ', heldline, _infile_);

  putlog // _N_ / '# ' _infile_ / '* ' heldline;

  retain heldline;

  if countc(heldline,'|') = 21 then do;
    _infile_ = heldline;                    /* proper number of delimiters, push heldline into input buffer */
    input @1 schedule: occ: desc: v1-v19;   /* read 'data' */
    OUTPUT;
    heldline = '';                          /* clear heldline */
  end;

  drop heldline;
  format v1-v16 $4. v17-v19 4. v2 $6.;
run;

Примечание:

Пример НЕ будет работать, когда данные считываются из DATALINES. Шаг DATA, который присваивает значение DATALINES infile , заставит входной буфер урезаться до 80 символов.

0 голосов
/ 04 апреля 2020

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

Таким образом, при условии, что у вас есть fileref с именем TXT, который указывает на исходный файл , Вот код для преобразования этого в новый файл с удаленным лишним символом конца строки. Ожидается, что в каждой строке будет 22 поля.

filename fix temp;
data _null_;
  infile txt ;
  file fix;
  input ;
  nwords=countw(_infile_,'|','mq');
  putlog _n_= nwords= _infile_;
  put _infile_ @;
  total+nwords;
  if total>=22 then do; put ; total=0; end;
  else put ' ' @;
run;

Мы можем прочитать строки обратно, чтобы убедиться, что это работает.

492   data _null_;
493     infile fix;
494     input ;
495     nwords=countw(_infile_,'|','mq');
496     putlog _n_= nwords= _infile_;
497   run;

NOTE: The infile FIX is:
      Filename=...\#LN00081,
      RECFM=V,LRECL=32767,File Size (bytes)=523,
      Last Modified=04Apr2020:11:29:46,
      Create Time=04Apr2020:11:29:46

_N_=1 nwords=22 9450007|23023|Reporter||33100|||||1|||||||||D||49|1
_N_=2 nwords=22 9451007|23023|Reporter||43086||||||1||||||||E||50|1
_N_=3 nwords=22 9462034|11021|Manager Oversee all operations, report to board of director|||||||||12|||||||F||1|12
_N_=4 nwords=22 9460034|43061|Office Assistant Schedule client appointments, enter visit|||||10|||||||||||B||3|10
_N_=5 nwords=22 9451002|24011|Engineer, Market Exempt||86353||||||||1||||||G||28|1
_N_=6 nwords=22 9450002|12021|Market President/Chief Revenue Officer||135000||||||||||1||||I||29|1
_N_=7 nwords=22 9460027|11111|Mgr, Emergency Care||131248||||||||||1||||I||208|1
NOTE: 7 records were read from the infile FIX.
      The minimum record length was 51.
      The maximum record length was 98.

Теперь вы можете читать файл в обычном режиме;

data want;
  infile fix dsd dlm='|' truncover;
  input schedule :$12. occ :$8. desc :$300. (v1-v16) (:$8.) v17-v19;
run;
...