BookmarkSubscribeRSS Feed
Anmolkhandelwal
Obsidian | Level 7

I have been trying to create a txt file with a format such as 1st row as header, from 2nd row i have datalines and last row as a trailer record. Requirement is LF(line feed) as record terminator. With the current code I am able to achieve LF as the record terminator, but this adds a extra blank line at end of file(which is not required).  Any solution for this would help.

my code looks like:

 

%let _PREX12_FILE = &_ddpath.&_dd_sdir./&FILENAME..txt;   this is my path to unix server where file will be created

DATA _NULL_;
SET &INFILE._HDR ;
FILE "&_PREX12_FILE." NEW TERMSTR=LF recfm=n ;
%PREX12_HDR;
RUN;

DATA _NULL_;
SET &INFILE._UNION_DATA;
FILE "&_PREX12_FILE." MOD ;
IF RECORD_TP_FLAG = '0100' THEN
PUT %PUT_CSV_100;

RUN;

DATA _NULL_;
SET &INFILE._TLR ;     /this is my input dataset containig a single line trailer data*/
FILE "&_PREX12_FILE." MOD TERMSTR=LF  ;

PUT

RECORD_TYPE $7.
REC_CNT $10.
FILE_DATE YYMMDDN.
FILE_TIME B8601TM6.
TRANS_CNT $10.
TRANS_AMT $15.
FILLER $100.

;

RUN;


 

I had tried using the RECFM = n option inthe last DATA _null_ step but no success.

17 REPLIES 17
Anmolkhandelwal
Obsidian | Level 7

Tried over the Unix server and also transfering over windows server.

Anmolkhandelwal
Obsidian | Level 7

ttaching the Text file which i have exported. My concerned line is the highlighted one.

 

Anmolkhandelwal
Obsidian | Level 7

No. Just the spaces till the End of line.

Kurt_Bremser
Super User

I ran this code:

DATA _NULL_;

FILE "$HOME/sascommunity/test.txt" NEW TERMSTR=LF ;
put 'Header';
RUN;

DATA _NULL_;
SET sashelp.class;
FILE "$HOME/sascommunity/test.txt" MOD ;
put (_all_) (:);

RUN;

DATA _NULL_;
record_type = 'TRAILER';
rec_cnt = '     10600';
file_date = '23jan2020'd;
file_time = '04:44:17't;
trans_cnt = '       500';
trans_amt = '        2207418';
length filler $100;
filler = "";
FILE "$HOME/sascommunity/test.txt" MOD TERMSTR=LF  ;

PUT

RECORD_TYPE $7.
REC_CNT $10.
FILE_DATE YYMMDDN.
FILE_TIME B8601TM6.
TRANS_CNT $10.
TRANS_AMT $15.
FILLER $100.

;

RUN;

and the file ended with the single '0A'x after the 100 bytes of the filler. Are you sure that there's no additional step trying to write to the file?

How many blanks do you have in that last incomplete line?

Anmolkhandelwal
Obsidian | Level 7

Nope not writing any thing to the file after the trailer line.

Following  it as the above code.

yabwon
Amethyst | Level 16

Hi @Anmolkhandelwal ,

 

Maybe this will help you:

 

filename f temp;

data _null_;
  file f recfm=n;
  if _N_ = 1 then put "This is header" '0a'x @;
  set sashelp.class end=eof;
  put age name height '0a'x @;
  if eof then put "This is footer";
run;

 

All the best

Bart

_______________
Polish SAS Users Group: www.polsug.com and communities.sas.com/polsug

"SAS Packages: the way to share" at SGF2020 Proceedings (the latest version), GitHub Repository, and YouTube Video.
Hands-on-Workshop: "Share your code with SAS Packages"
"My First SAS Package: A How-To" at SGF2021 Proceedings

SAS Ballot Ideas: one: SPF in SAS, two, and three
SAS Documentation



Tom
Super User Tom
Super User

We cannot test with the code you posted since we do not have either the input data or the definition of the macros you are calling.

 

But I suspect that the file is fine and there is some type of misunderstanding about how text files are constructed.

 

It sounds like whatever tool you are using to look at the file is showing an extra line.  If you are using a text editor then they will generally show an extra line so that you have some place to type new text you want to add at the end.

 

To check how the file really ends read the file using a SAS data step and dump the text using $HEX format to see exactly what is there at the end.  For a small sample file just dump the whole file.  To test a larger file you might want to skip the beginning so as not to flood the log with information you don't need.

filename text temp;
data _null_;
  file test;
  put 'line one'
    / 'line two'
  ;
run;

data _null_;
  infile test recfm=f lrecl=10;
  input;
  list;
run;
RULE:     ----+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+--

1   CHAR  line one..
    ZONE  6666266600
    NUMR  C9E50FE5DA

2   CHAR  line two..
    ZONE  6666277600
    NUMR  C9E5047FDA
NOTE: 2 records were read from the infile TEST.

As you can see in this example, run on Windows, each line ends with CR and LF characters (0D and 0A in hex codes).

 

Some programs (programmers?) have a mental model of a file as a series of records instead of a series of lines. In this model they think it makes sense to not include that final end of line marker at the end of the file.  So when it is there they think it means there is a "record" with zero bytes at the end of the file.

 

If you cannot fix the system that is reading the file to accept text files as they should be constructed then you need to tell SAS not the write the end of line on the last line.  One way is to write the file using RECFM=N and explicitly write the end of line, or record separators, manually.

filename text temp;
data _null_;
  file test recfm=n ;
  put 'line one' '0D0A'x
    / 'line two' 
  ;
run;

To make it easier you might just add the last line separately from the other lines.

 

filename text temp;
data _null_;
  file test ;
  put 'line one' 
    / 'line two' 
  ;
run;

data _null_;
  file test mod recfm=n ;
  put 'last line' ;
run;

As you can see the last line will be just 9 bytes long and not have any end of line characters.

RULE:     ----+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+--

1   CHAR  line one..
    ZONE  6666266600
    NUMR  C9E50FE5DA

2   CHAR  line two..
    ZONE  6666277600
    NUMR  C9E5047FDA
3         last line 9

 

 

Anmolkhandelwal
Obsidian | Level 7

I have tried this approach. Tried writing the last line in a different data _null_ with recfm = n and no "0a" as terminator with my put statements, this does remove the extra line that was created earlier but the terminator for this trailer comes to be blank. i am trying to get the terminator as LF for last line without generating a blank line after that.

 

 

Kurt_Bremser
Super User

I just reran my code from my previous post on University Edition on a Mac, and inspected the resulting text file with hexdump. There is one single '0a'x at the end of the file after the filler, and no additional blanks. So those additional blanks must be added by something else you use after SAS writes the file.

hackathon24-white-horiz.png

2025 SAS Hackathon: There is still time!

Good news: We've extended SAS Hackathon registration until Sept. 12, so you still have time to be part of our biggest event yet – our five-year anniversary!

Register Now

How to Concatenate Values

Learn how use the CAT functions in SAS to join values from multiple variables into a single value.

Find more tutorials on the SAS Users YouTube channel.

SAS Training: Just a Click Away

 Ready to level-up your skills? Choose your own adventure.

Browse our catalog!

Discussion stats
  • 17 replies
  • 5144 views
  • 0 likes
  • 5 in conversation