6

Shapefile comes with a bunch of friends (often referred to as sidecar files) that all need to have the same basename. While software like QGIS deals with that very well I sometimes have the need to script this in a shell script / like to do this from the terminal without starting a GUI tool.

As @Vince mentioned in the comment, simply renaming is not a good idea "The safest way to rename a shapefile is to use a shapefile-aware utility."

Given a set of shapefile

  • oldname.shp
  • oldname.shx
  • oldname.cpg
  • oldname.dbf
  • oldname.prj

How can a shapefile be renamed via terminal (bash) only?

4
  • I am worried about all those "Close" votes, probably motivated by this being mostly bash. Before clicking this "Close" button. I think it's a common problem and will help some people googling for "rename shapefile terminal". In my experience, this is a very shapefile (gis) specific problem. Oct 20 at 11:54
  • 2
    The safest way to rename a shapefile is to use a shapefile-aware utility. Incomplete script execution could corrupt the dataset.
    – Vince
    Oct 20 at 18:17
  • @Vince if you know such a utility that works in a terminal, then your answer is more than welcome. My own answer with the "brute force" attack certainly has its caveats. Oct 20 at 20:27
  • 1
    I have voted to reopen this as manipulating shapefiles is a very common GIS practice.
    – Aaron
    Nov 22 at 17:10
9

Expanding from this answer https://stackoverflow.com/questions/9558986/what-does-the-curly-brace-syntax-var-mean/9559024#9559024 it is possible to do

for f in oldname.*; do 
  mv  -- "$f" "newname${f#oldname}"
done
1
  • I hope it's ok to use gis.se as a personal notepad for howto's of broader interest Oct 20 at 9:27
5

If you have rename installed on you system, you can also use:

rename oldname newname oldname.*

or if you prefer a regex:

rename 's/oldname/newname/g' oldname.*

If you don't have rename, you can install it with your package manager, e.g. apt:

sudo apt install rename
4

Here is my little tool to "move shapes" coded in Perl. If more "sidecar files" show up, append them to the line.

# Shape file extention candidates + so called side car files

my @ext = qw(shp shx dbf prj sbn sbx fbn fbx atx ixs mxs cpg);

May be it is a little bit noisy in terms of output.

#!/usr/bin/env perl
# ------------------------------------------------------------
# shpmv -- Tool to rename ESRI Shape files
# ------------------------------------------------------------
# Copyright (C) 2016 Alexander Weidauer
# Contact: alex.weidauer@huckfinn.de
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
# ------------------------------------------------------------
use strict;
use File::Copy qw(move);
use File::Basename;
use File::Spec;

# Read command line parameter $1 $2 and $3
my $src  = shift; # Source location
my $dst  = shift; # Destination
my $case = shift; # Extention handling upper or lower case

# Parameter handling and help function
if ( ($src eq '-h') or ($src eq '--help') ) {
    print "Move ESRI Shape files\n\n";
    print "Usage:     $0 source-file destination [-l|-u]\n";
    print "Parameter:\n";
    print "  source-file -- Shapefile for the ensemble to move from.\n";
    print "  destination -- Shapefile destination without extension to move to.\n\n";
    print "Optional:\n";
    print "  -l extention lower case\n";
    print "  -u extention upper case\n\n";
    print "Example:   $0 ~/geodata/long_name.shp ~/data/short_name\n";
    exit 0;
}


# Shape file extention candidates + so called side car files
my @ext = qw(shp shx dbf prj sbn sbx fbn fbx atx ixs mxs cpg);

# Check parameter correctness and availability
die "Missing source Shapefile\n" if ! $src;
die "Missing destination name\n"   if ! $dst;

 # Lower case is the default switch
$case //= '-l';

# Make path an file management absolute
$src = File::Spec->rel2abs($src);
$dst = File::Spec->rel2abs($dst);

# Strip the extention from the input and
# check source and destination path
my ($sname, $spath, $suffix) = fileparse($src, '\.[^\.]*');
$src = File::Spec->catfile($spath,$sname);
die "Source '$spath' path does not exist!\n" if ! (-d $spath);

if ( ($dst =~ /\.shp$/) or ($dst =~ /\.SHP$/) ) {
   print "WARNING remove extention from destiantion '$dst'\n";
   $dst =~ s/\.shp$//;
   $dst =~ s/\.SHP$//;
}

my ($dname, $dpath, $duffix) = fileparse($dst, '\.[^\.]*');
die "Destination path '$dpath' does not exist\n"
    if not -d $dpath;

print "Move ESRI shape files\n";
print "    from: $src\n";
print "      to: $dst\n";

# Check files to move
my @suffix=();
for my $ix (0..$#ext) {
    my $lext  = $ext[$ix];
    my $uext  = uc($lext);
    my $lname = $src.'.'.$lext;
    my $uname = $src.'.'.$uext;
    my $done  = 0;
    print "  ..test $sname(".$lext."|".$uext.")";
    if (-r $lname) {
        push (@suffix, $lext) if (-e $lname);
        $done = 1;
    }
    if (-r $uname) {
        push (@suffix, $uext) if (-e $uname);
        $done = 1;
    }
    if  (! $done) {
        print " N/A\n";
        die "Cannot read one of the essential shape ".
            "files with extension $lext|$uext\n" if $ix < 3;
    } else {
        print " OK\n" if $done;
    }
}

# Proceed move operation
for my $sext (@suffix) {
    my $text = $sext;
    $text = lc($text) if $case eq '-l';
    $text = uc($text) if $case eq '-u';
    my $sfile = $src.".".$sext;
    my $tfile = $dst.".".$text;
    print "  ..move from: $sfile\n";
    print "           to: $tfile";
    move($sfile, $tfile) or die "\nCannot move file $sfile!\n";
    print " OK\n";
}
print ".READY\n";

# --- EOF ----------------------------------------------------
5
  • Ha, all I want now is a package that I can apt-get or dnf install :-) Oct 20 at 20:28
  • Hm, I could pack this with CPAN further ..DEBIAN CPAN.. conform stuff etc. ... But it is IMO some kind of day hack to put into $HOME/bin/shpmv ? And if you want to pack this feel free. it is only some lines of day work code :-)
    – huckfinn
    Oct 20 at 22:17
  • I guess if it's me, it's gonna be faster to re-write this in python and make it available via pip install shpmv but up to now I can't think of a situation where the answer by @suricactus wouldn't have had the best bang for the buck. Oct 20 at 23:16
  • Yes feel free, re-python and pip it. Its only some code with a help advise hot to use the tool.
    – huckfinn
    Oct 21 at 6:25
  • Will do when I run into a limitation with the other approaches Oct 21 at 9:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.