diff --git a/perl-xCAT/xCAT/NodeRange.pm b/perl-xCAT/xCAT/NodeRange.pm
index a06364efd..d6bf2954f 100644
--- a/perl-xCAT/xCAT/NodeRange.pm
+++ b/perl-xCAT/xCAT/NodeRange.pm
@@ -7,7 +7,7 @@ use strict;
 #Perl implementation of noderange
 our @ISA = qw(Exporter);
 our @EXPORT = qw(noderange nodesmissed);
-our @EXPORT_OK = qw(extnoderange);
+our @EXPORT_OK = qw(extnoderange abbreviate_noderange);
 
 my $missingnodes=[];
 my $nodelist; #=xCAT::Table->new('nodelist',-create =>1);
@@ -241,6 +241,51 @@ sub extnoderange { #An extended noderange function.  Needed as the more straight
     @allnodeset=();
     return $return;
 }
+sub abbreviate_noderange { 
+    #takes a list of nodes or a string and abbreviates
+    my $nodes=shift;
+    my %grouphash;
+    my %sizedgroups;
+    my %nodesleft;
+    my %targetelems;
+    unless (ref $nodes) {
+        $nodes = noderange($nodes);
+    }
+    %nodesleft = map { $_ => 1 } @{$nodes};
+    unless ($nodelist) { 
+        $nodelist =xCAT::Table->new('nodelist',-create =>1); 
+    }
+    my $group;
+	foreach($nodelist->getAllAttribs('node','groups')) {
+		my @groups=split(/,/,$_->{groups}); #The where clause doesn't guarantee the atom is a full group name, only that it could be
+        foreach $group (@groups) {
+            push @{$grouphash{$group}},$_->{node};
+        }
+    }
+
+    foreach $group (keys %grouphash) {
+        push @{$sizedgroups{scalar @{$grouphash{$group}}}},$group;
+    }
+    my $node;
+    use Data::Dumper;
+    print Dumper(\%sizedgroups);
+    foreach (reverse sort {$a <=> $b} keys %sizedgroups) {
+        GROUP: foreach $group (@{$sizedgroups{$_}}) {
+                foreach $node (@{$grouphash{$group}}) {
+                    unless (grep $node eq $_,keys %nodesleft) {
+                    #this group contains a node that isn't left, skip it
+                        next GROUP;
+                    }
+                }
+                foreach $node (@{$grouphash{$group}}){
+                    delete $nodesleft{$node};
+                }
+                $targetelems{$group}=1;
+        }
+    }
+    return (join ',',keys %targetelems,keys %nodesleft);
+}
+
 sub noderange {
   $missingnodes=[];
   #We for now just do left to right operations
diff --git a/xCAT-client/bin/xcoll b/xCAT-client/bin/xcoll
index 4699e7f58..70f85ce75 100755
--- a/xCAT-client/bin/xcoll
+++ b/xCAT-client/bin/xcoll
@@ -1,6 +1,10 @@
 #!/usr/bin/env perl
 # IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
+BEGIN { $::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : -d '/opt/xcat' ? '/opt/xcat' : '/usr'; }
+use lib "$::XCATROOT/lib/perl";
 use Data::Dumper;
+use xCAT::Client;
+use strict;
 my %output;
 while (<STDIN>) {
     my $node;
@@ -18,11 +22,24 @@ my %collated;
 foreach (keys %output) {
     $collated{$output{$_}}->{$_}=1;
 }
-foreach (keys %collated) {
-    my $nodes = join(',',sort (keys %{$collated{$_}}));
+
+my $nodes;
+sub fillerup {
+    my $response = shift;
+    if ($response->{data}->[0]) {
+        $nodes = $response->{data}->[0];
+    }
+}
+foreach my $output (keys %collated) {
+    $nodes = join(',',sort (keys %{$collated{$output}}));
+    my $cmdref = {
+        noderange => [$nodes],
+        command => ['rnoderange'],
+    };
+    xCAT::Client::submit_request($cmdref,\&fillerup);
     print "====================================\n";
     print "$nodes\n";
     print "====================================\n";
-    print $_;
+    print $output;
     print "\n";
 }
diff --git a/xCAT-server/lib/xcat/plugins/tabutils.pm b/xCAT-server/lib/xcat/plugins/tabutils.pm
index d1f8a5c6e..86bc9da6d 100644
--- a/xCAT-server/lib/xcat/plugins/tabutils.pm
+++ b/xCAT-server/lib/xcat/plugins/tabutils.pm
@@ -11,7 +11,7 @@ use warnings;
 use xCAT::Table;
 use xCAT::Schema;
 use Data::Dumper;
-use xCAT::NodeRange;
+use xCAT::NodeRange qw/abbreviate_noderange/;
 use xCAT::Schema;
 use xCAT::Utils;
 use Getopt::Long;
@@ -46,6 +46,7 @@ sub handled_commands
             delattr    => "tabutils",     # not implemented yet
             chtype     => "tabutils",     # not implemented yet
             nr         => "tabutils",     # not implemented yet
+            rnoderange => "tabutils",     # not implemented yet
             tabgrep    => "tabutils"
             };
 }
@@ -89,6 +90,10 @@ sub process_request
     {
         return nodels($nodes, $args, $callback, $request->{emptynoderange}->[0]);
     }
+    elsif ($command eq "rnoderange") 
+    {
+        return rnoderange($nodes,$args,$callback);
+    }
     elsif ($command eq "noderm" or $command eq "rmnode")
     {
         return noderm($nodes, $args, $callback);
@@ -833,6 +838,16 @@ sub tabgrep
 
 }
 
+sub rnoderange 
+{
+    my $nodes = shift;
+    my $args = shift;
+    my $callback = shift;
+    my $data = abbreviate_noderange($nodes);
+    if ($data) {
+        $callback->({data=>[$data]});
+    }
+}
 #####################################################
 #  nodels command
 #####################################################