Macros for SAS Application Developers
https://github.com/sasjs/core
Loading...
Searching...
No Matches
mp_cleancsv.sas
Go to the documentation of this file.
1/**
2 @file
3 @brief Fixes embedded cr / lf / crlf in CSV
4 @details CSVs will sometimes contain lf or crlf within quotes (eg when
5 saved by excel). When the termstr is ALSO lf or crlf that can be tricky
6 to process using SAS defaults.
7 This macro converts any csv to follow the convention of a windows excel file,
8 applying CRLF line endings and converting embedded cr and crlf to lf.
9
10 Usage:
11
12 fileref mycsv "/path/your/csv";
13 %mp_cleancsv(in=mycsv,out=/path/new.csv)
14
15 @param [in] in= (NOTPROVIDED)
16 Provide path or fileref to input csv. If a period is
17 found, it is assumed to be a file.
18 @param [in] out= (NOTPROVIDED) Output path or fileref to output csv.
19 If a period is found, it is assumed to be a file.
20 @param [in] qchar= ('22'x) Quote char - hex code 22 is the double quote.
21
22 @version 9.2
23 @author Allan Bowe
24 @cond
25**/
26
27%macro mp_cleancsv(in=NOTPROVIDED,out=NOTPROVIDED,qchar='22'x);
28%if "&in"="NOTPROVIDED" or "&out"="NOTPROVIDED" %then %do;
29 %put %str(ERR)OR: Please provide valid input (&in) & output (&out) locations;
30 %return;
31%end;
32
33/* presence of a period(.) indicates a physical location */
34%if %index(&in,.) %then %let in="&in";
35%if %index(&out,.) %then %let out="&out";
36
37/**
38 * convert all cr and crlf within quotes to lf
39 * convert all other cr or lf to crlf
40 */
41 data _null_;
42 infile &in recfm=n ;
43 file &out recfm=n;
44 retain isq iscrlf 0 qchar &qchar;
45 input inchar $char1. ;
46 if inchar=qchar then isq = mod(isq+1,2);
47 if isq then do;
48 /* inside a quote change cr and crlf to lf */
49 if inchar='0D'x then do;
50 put '0A'x;
51 input inchar $char1.;
52 if inchar ne '0A'x then do;
53 put inchar $char1.;
54 if inchar=qchar then isq = mod(isq+1,2);
55 end;
56 end;
57 else put inchar $char1.;
58 end;
59 else do;
60 /* outside a quote, change cr and lf to crlf */
61 if inchar='0D'x then do;
62 crblank:
63 put '0D0A'x;
64 input inchar $char1.;
65 if inchar='0D'x then do;
66 /* multiple CR indicates CR formatted file with blank lines */
67 goto crblank;
68 end;
69 else if inchar ne '0A'x then do;
70 put inchar $char1.;
71 if inchar=qchar then isq = mod(isq+1,2);
72 end;
73 end;
74 else if inchar='0A'x then put '0D0A'x;
75 else put inchar $char1.;
76 end;
77 run;
78%mend mp_cleancsv;
79/** @endcond */