3

I happened to need the attribute names of a large number of .shp files. Is it possible under Linux, without importing the files into a GIS?

2
  • 1
    Uhm.. not sure: why the downvotes? Did I ask a "wrong" question? Commented Jul 20, 2019 at 12:49
  • Thanks, I see, even if I simultaneously answered my own question... Maybe it was the wrong way to handle this? Commented Jul 20, 2019 at 13:05

2 Answers 2

3

You have a QGIS tag and in QGIS you can do:

import os
shapefolder = r'/home/bera/GIS/ok_riks_Sweref_99_TM_shape/oversikt/riks/'

shapefiles = [os.path.join(shapefolder,f) for f in os.listdir(shapefolder) if os.path.isfile(os.path.join(shapefolder, f)) and f.endswith('.shp')]

for shapefile in shapefiles:
    layer = QgsVectorLayer(shapefile, 'templyr')
    print(os.path.basename(shapefile)+' '+' '.join([f.name() for f in layer.fields()]))

Output:

al_riks.shp KKOD KATEGORI ADAT
nv_riks.shp KKOD KATEGORI NAMN1 NAMN2 ADAT
mb_riks.shp KKOD KATEGORI TATNR LANSKOD AREASCB BEF NAMN1 NAMN2 ADAT
hl_riks.shp KKOD KATEGORI NAMN1 NAMN2 ADAT
2
  • Thanks, that is useful if shapefiles have already been imported in QGIS. In my specific I was looking for a more generic method, to extract the attributes directly from files/archives, without prior import. Commented Jul 20, 2019 at 12:44
  • 2
    Nice. No you dont have to import anything, just change the shapefolder variable and run it.
    – Bera
    Commented Jul 20, 2019 at 12:46
3

Under Linux, from the command line, one can neatly use unoconv to batch convert the associated .dbf files into .csv streams, pipe it through head and extract only the file name and the first line, which contains the headers:

apt-get install unoconv
ls -1 */*.dbf |xargs -n1 -I{} sh -c 'echo {};unoconv -f csv --stdout {}|head -n1'

The output will be similar to this:

shapefile_1/shapefile_1.dbf
"ID,N,16,0","NAME,C,40","ATTR1,C,8","ATTR2,C,8","ATTR3,C,8","ATTR4,C,16","ATTR5,C,25","ATTR6,C,22","ATTR7,C,66","ATTR8,C,20","ATTR9,N,16,5"
shapefile_2/shapefile_2.dbf
"AREA,N,19,11","ID,C,20","ATTR1,C,8","ATTR2,C,8","ATTR3,C,8","ATTR4,C,16","ATTR5,C,25","ATTR6,C,22"
shapefile_3/shapefile_3.dbf
...

If you want to have just the clean names (i.e. without the bdf type specifications):

ls -1 */*.dbf |xargs -n1 -I{} sh -c 'echo {};unoconv -f csv --stdout {}|head -n1'|sed 's/","/@/g'|sed 's/"$/@/'|sed 's/,[A-Z0-9,]*@/ /g'

which outputs:

shapefile_1/shapefile_1.dbf
ID NAME ATTR1 ATTR2 ATTR3 ATTR4 ATTR5 ATTR6 ATTR7 ATTR8 ATTR9
shapefile_2/shapefile_2.dbf
AREA ID ATTR1 ATTR2 ATTR3 ATTR4 ATTR5
shapefile_3/shapefile_3.dbf
...

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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