You can use $LS_COLORS to do this. If your version of ls supports specifying the colors using that variable, you can define output per file type. It's builtin behavior and very configurable. So I created some files to demo this like:
for f in 9 8 7 6 5 4 3 2 1 do touch "${f}file" && ln -s ./"${f}file" ./"${f}filelink" done
So now I'll do:
LS_COLORS='lc=:rc=:ec=:ln=\n\n\0HERE_THERE_BE_A_LINK>>\0:' \ ls -1 --color=always | cat ###OUTPUT### 1file HERE_THERE_BE_A_LINK>>1filelink@ 2file HERE_THERE_BE_A_LINK>>2filelink@ 3file ... HERE_THERE_BE_A_LINK>>8filelink@ 9file ...
And the nulls are there too...
LS_COLORS='lc=:rc=:ec=:ln=\n\n\0HERE_THERE_BE_A_LINK>>\0:' \ ls -1 --color=always | sed -n l 1file$ $ $ \000HERE_THERE_BE_A_LINK>>\0001filelink@$ 2file$ $ $ \000HERE_THERE_BE_A_LINK>>\0002filelink@$ 3file$ ...
You can specify for all or any filetypes. Doing so for only a single filetype might not get you want though as ls has incorporated some defaulted compilation values for terminal escapes. You'd do much better to address the api as a single interface. Here's a simple little means of parsing and assigning current environment dircolors configured defaults:
LS_COLORS='rs=:no=//:lc=:rc=:ec=//:'$( set -- di fi ln mh pi so do bd cd or su sg ca tw ow st ex for fc do printf %s "$fc=/$fc//:" done) ls -l --color=always | cat
Its output in my home directory looks like this:
total 884 ///-rw-r--r-- 1 mikeserv mikeserv 793 Jul 9 11:23 /fi//1/ //drwxr-xr-x 1 mikeserv mikeserv 574 Jun 24 16:50 /di//Desktop// //-rw-r--r-- 1 mikeserv mikeserv 166 Jul 4 23:02 /fi//Terminology.log/ //-rw-r--r-- 1 mikeserv mikeserv 0 Jul 6 11:24 /fi//new file/ //lrwxrwxrwx 1 mikeserv mikeserv 10 Jul 11 04:18 /ln//new file link/ -> /fi//./new file/ //-rwxr-xr-x 1 mikeserv mikeserv 190 Jun 22 11:26 /ex//script.sh/* //-rw-r--r-- 1 mikeserv mikeserv 433568 Jun 22 17:10 /fi//shot-2014-06-22_17-10-16.jpg/ //-rw-r--r-- 1 mikeserv mikeserv 68 Jun 17 19:59 /fi//target.txt/
You can run that with cat -A too and the only difference you'll encounter is that you'll see $ for newlines - there are no unprintable characters introduced by ls --color=always with this configuration - only what you see here.
ls inserts its default terminal escapes like this:
${lc}${type_code}${rc}FILENAME${lc}${rs}${rc}
...where the default values for $lc (left of code), $rc (right of code), and $rs (reset) are:
\033 - ESCAPE m - END ESCAPE 0 - reset
...respectively. ${type_code} is used to stand in for the various fi (regular file - default unset), di (directory), ln (link), and every other file type I know of. There is also $no (normal) which is also by default unset and which is here represented by the // at the beginning of each line. My simple little IFS=: block works just by inserting the name for each configurable in also as its own value and adding a slash or two - though \0NUL bytes would do as well.
By default ls will also insert one $rs immediately preceding its first output $lc - but this is not accurately represented here. In this case I have specified $ec (end code) which stands in for $rs in all cases - when it is specified you don't get an extra $rs between $no and ${type_code} as you would otherwise - it only presents immediately following a filename and once at the start of output - as you can see in the one extra slash at the head of line one.
Here's a snippet from my own $LS_COLORS
printf %s "$LS_COLORS" rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:\ so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:\ or=40;31;01:su=37;41:sg=30;43:ca=30;41:\ tw=30;42:ow=34;42:st=37;44:ex=01;32:\ *.tar=01;31:*.tgz=01;31:*.arc=01;31:*.arj=01;31:...
And, in truth, my little shell hack is probably overly complicated - there's a widely available interface for assigning these values. Try dircolors -p in your cli and info dircolors for more information on that.
You can wrap the filenames in arbitrary strings. You can comment them out if you wish. You can specify similar behaviors based only on file extension. There's really not a lot you can't specify that way.
Now I'm not just making all of this up either - I learned about it after stumbling on the source code by accident.
With this particular configuration ls will emit:
$no - once per record at the start of each record
${type_code} - once immediately preceding each filename to include an abbreviation of the file's type and always occurring on the same line as and 7 whitespace delimited fields after $no or immediately following a -> denoting a symbolic link's target.
$ec - once immediately preceding the very first line and thereafter only once immediately following each filename.
All other values are empty.
What follows is a null-delimited ls, and this time I will use cat -A, though, without it, it would look the same as the last example :
LS_COLORS='rs=:no=\0//:lc=:rc=:ec=\0//:'$( set -- di fi ln mh pi so do bd cd or su sg ca tw ow st ex for fc do printf %s "$fc=/$fc//\0:" done) ls -l --color=always | cat -A total 884$ ^@//^@//-rw-r--r-- 1 mikeserv mikeserv 793 Jul 9 11:23 /fi//^@1^@//$ ^@//drwxr-xr-x 1 mikeserv mikeserv 574 Jun 24 16:50 /di//^@Desktop^@///$ ^@//-rw-r--r-- 1 mikeserv mikeserv 166 Jul 4 23:02 /fi//^@Terminology.log^@//$ ^@//-rw-r--r-- 1 mikeserv mikeserv 0 Jul 6 11:24 /fi//^@new$ file^@//$ ^@//lrwxrwxrwx 1 mikeserv mikeserv 10 Jul 11 04:18 /ln//^@new$ file$ link^@// -> /fi//^@./new$ file^@//$ ^@//-rwxr-xr-x 1 mikeserv mikeserv 190 Jun 22 11:26 /ex//^@script.sh^@//*$ ^@//-rw-r--r-- 1 mikeserv mikeserv 433568 Jun 22 17:10 /fi//^@shot-2014-06-22_17-10-16.jpg^@//$ ^@//-rw-r--r-- 1 mikeserv mikeserv 68 Jun 17 19:59 /fi//^@target.txt^@//$
And so to reliably remove all symbolic links from a -long listing like this one, you might make a simple change:
LS_COLORS='rs=:no=//:lc=:rc=:ec=/ :'$( set -- di fi mh pi so do bd cd or su sg ca tw ow st ex for fc do printf %s "$fc=$fc/:" done)ln=///: ls -l --color=always | sed ':ln \|///|{N;\|\n//|!bln};s|.*//||'
My results after running that look like...
total 884 -rw-r--r-- 1 mikeserv mikeserv 793 Jul 9 11:23 fi/1/ drwxr-xr-x 1 mikeserv mikeserv 574 Jun 24 16:50 di/Desktop/ / -rw-r--r-- 1 mikeserv mikeserv 166 Jul 4 23:02 fi/Terminology.log/ -rw-r--r-- 1 mikeserv mikeserv 0 Jul 6 11:24 fi/new file/ -rwxr-xr-x 1 mikeserv mikeserv 190 Jun 22 11:26 ex/script.sh/ * -rw-r--r-- 1 mikeserv mikeserv 433568 Jun 22 17:10 fi/shot-2014-06-22_17-10-16.jpg/ -rw-r--r-- 1 mikeserv mikeserv 68 Jun 17 19:59 fi/target.txt/
Using some command like to the one I do above:
LSCOLORS=...$(...)fc1=///:fc2=///: ls ... | sed ...
...(where fc1 and fc2 are filetypes listed after set -- in the subshell) should serve to reliably remove any combinations of filetypes you could want from ls output regardless of any characters the filenames might contain.