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?

Taras
  • 32,823
  • 4
  • 66
  • 137
Matthias Kuhn
  • 27,780
  • 3
  • 88
  • 129
  • 1
    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. – Matthias Kuhn Oct 20 '21 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 '21 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. – Matthias Kuhn Oct 20 '21 at 20:27
  • 3
    I have voted to reopen this as manipulating shapefiles is a very common GIS practice. – Aaron Nov 22 '21 at 17:10

3 Answers3

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
Matthias Kuhn
  • 27,780
  • 3
  • 88
  • 129
6

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
suricactus
  • 301
  • 1
  • 6
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 ----------------------------------------------------

huckfinn
  • 3,583
  • 17
  • 35
  • Ha, all I want now is a package that I can apt-get or dnf install :-) – Matthias Kuhn Oct 20 '21 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 '21 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. – Matthias Kuhn Oct 20 '21 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 '21 at 06:25
  • Will do when I run into a limitation with the other approaches – Matthias Kuhn Oct 21 '21 at 09:03