/*
/ Program : hexchars.sas
/ Version : 2.1
/ Author : Roland Rashleigh-Berry
/ Date : 02-Jul-2011
/ Purpose : To show up ascii non-printables characters in a flat file by
/ displaying their ascii codes as hexadecimal numbers in "< >"
/ symbols.
/ SubMacros : none
/ Notes : Files path can be quoted or unquoted. If you are using this to
/ look for invisible delimiters in a ".csv" file then these
/ invisible delimiters are almost certainly the horizontal tab
/ character "09"x. To find out then use this macro as in the first
/ example usage notes and you will see "<09>" (or a different value)
/ in the log and once you know you can use "proc import" to read in
/ the file using this syntax:
/ PROC IMPORT DATAFILE="myfile.ext" OUT=mydset DBMS=DLM REPLACE;
/ DELIMITER="09"x;
/ GETNAMES=YES;
/ RUN;
/ Alternately, you can use the %dlm2sas macro to read in a file and
/ create a dataset but that macro can only read simple files and
/ will create only character fields of a uniform length.
/ Usage : %hexchars(infile.ext)
/ %hexchars(infile.ext,"outfile.ext")
/ %hexchars(infile.ext,outfile.ext)
/ %hexchars("infile.ext")
/ %hexchars("infile.ext",print)
/ %hexchars("infile.ext","log")
/===============================================================================
/ PARAMETERS:
/-------name------- -------------------------description------------------------
/ infile (pos) Input file (quoted or unquoted)
/ file (pos) Output file (quoted or unquoted) (can be "print" or
/ "log"). Written to the log by default.
/===============================================================================
/ AMENDMENT HISTORY:
/ init --date-- mod-id ----------------------description------------------------
/ rrb 29Mar07 Put out "macro called" message plus header tidy
/ rrb 04May11 Code tidy
/ rrb 25Jun11 Renamed from %asciinonp and changed to enable output to
/ be written to print output or the log and made more
/ friendly for file quoting (v2.0)
/ rrb 02Jul11 Added check on input file existence (v2.1)
/===============================================================================
/ This is public domain software. No guarantee as to suitability or accuracy is
/ given or implied. User uses this code entirely at their own risk.
/=============================================================================*/
%put MACRO CALLED: hexchars v2.1;
%macro hexchars(infile,file);
%local err;
%let err=ERR%str(OR);
%if not %length(&infile) %then %do;
%put &err: (hexchars) No file path specified;
%goto exit;
%end;
%else %do;
%let infile=%sysfunc(dequote(&infile));
%if not %sysfunc(fileexist(&infile)) %then %do;
%put &err: (hexchars) File "&infile" can not be found;
%goto exit;
%end;
%end;
%if %length(&file) %then %let file=%sysfunc(dequote(&file));
data _null_;
length linein $ 256 newline $ 400 char $ 1;
retain outpos 0 ;
infile "&infile" pad;
%if not %length(&file) %then %do;
%end;
%else %if "%upcase(&file)" EQ "LOG" %then %do;
%end;
%else %if "%upcase(&file)" EQ "PRINT" %then %do;
file print notitles noprint;
%end;
%else %do;
file "&file" notitles noprint;
%end;
input linein $char256.;
outpos=1;
if linein ne ' ' then do;
do i=1 to length(linein);
char=substr(linein,i,1);
rank=rank(char);
if 32 <= rank <= 126 then do;
substr(newline,outpos,1)=char;
outpos=outpos+1;
end;
else do;
substr(newline,outpos,4)='<'||put(rank,hex2.)||'>';
outpos=outpos+4;
end;
end;
put @(length(newline)-length(left(newline))+1) newline;
end;
else put;
run;
%goto skip;
%exit: %put &err: (hexchars) Leaving macro due to problem(s) listed;
%skip:
%mend hexchars;