Search code examples
sedcygwinarcgis

split a large text (xyz) database into x equal parts


I want to split a large text database (~10 million lines). I can use a command like

$ sed -i -e '4 s/(dB)//' -e '4 s/Best\ unit/Best_Unit/' -e '1,3 d' '/cygdrive/c/                                                                                                                      Radio Mobile/Output/TRC_TestProcess/trc_longlands.txt'

$ split -l 1000000  /cygdrive/P/2012/Job_044_DM_Radio_Propogation/Working/FinalPropogation/TRC_Longlands/trc_longlands.txt 1

The first line is to clean the databse and the next is to split it - but then the output files do not have the field names. How can I incorporate the field names into each dataset and pipe a list which has the original file, new file name and line numbers (from original file) in it. This is so that it can be used in the arcgis model to re-join the final simplified polygon datasets.

ALTERNATIVELY AND MORE USEFULLY -as this needs to go into a arcgis model, a python based solution is best. More details are in https://gis.stackexchange.com/questions/21420/large-point-to-polygon-by-buffer-join-buffer-dissolve-issues#comment29062_21420 and Remove specific lines from a large text file in python

SO GOING WITH A CYGWIN based Python solution as per answer by icyrock.com

we have process_text.sh

cd  /cygdrive/P/2012/Job_044_DM_Radio_Propogation/Working/FinalPropogation/TRC_Longlands
mkdir processing
cp trc_longlands.txt processing/trc_longlands.txt
cd txt_processing
sed -i -e '4 s/(dB)//' -e '4 s/Best\ unit/Best_Unit/' -e '1,3 d' 'trc_longlands.txt'
split -l 1000000  trc_longlands.txt trc_longlands_
cat > a
h
1
2
3
4
5
6
7
8
9
^D
split -l 3
split -l 3 a 1
mv 1aa 21aa
for i in 1*; do head -n1 21aa|cat - $i > 2$i; done
for i in 21*; do echo ---- $i; cat $i; done

how can "TRC_Longlands" and the path be replaced with the input filename -in python we have %path%/%name for this. in the last line is "do echo" necessary?

and this is called by python using

import os
os.system("process_text.bat")

where process_text.bat is basically

bash process_text.sh

I get the following error when run from dos...

Microsoft Windows [Version 6.1.7601] Copyright (c) 2009 Microsoft Corporation. All rights reserved.

C:\Users\georgec>bash P:\2012\Job_044_DM_Radio_Propogation\Working\FinalPropogat ion\TRC_Longlands\process_text.sh 'bash' is not recognized as an internal or external command, operable program or batch file.

also when I run the bash command from cygwin -I get

georgec@ATGIS25 /cygdrive/P/2012/Job_044_DM_Radio_Propogation/Working/FinalPropogation/TRC_Longlands $ bash process_text.sh : No such file or directory: /cygdrive/P/2012/Job_044_DM_Radio_Propogation/Working/FinalPropogation/TRC_Longlands cp: cannot create regular file `processing/trc_longlands.txt\r': No such file or directory : No such file or directory: txt_processing : No such file or directoryds.txt

but the files are created in the root directory.enter image description here

why is there a "." after the directory name? how can they be given a .txt extension?


Solution

  • If you want to just prepend the first line of the original file to all but the first of the splits, you can do something like:

    $ cat > a
    h
    1
    2
    3
    4
    5
    6
    7
    ^D
    $ split -l 3
    $ split -l 3 a 1
    $ ls
    1aa 1ab 1ac a
    $ mv 1aa 21aa
    $ for i in 1*; do head -n1 21aa|cat - $i > 2$i; done
    $ for i in 21*; do echo ---- $i; cat $i; done
    ---- 21aa
    h
    1
    2
    ---- 21ab
    h
    3
    4
    5
    ---- 21ac
    h
    6
    7
    

    Obviously, the first file will have one line less then the middle parts and the last part might be shorter, too, but if that's not a problem, this should work just fine. Of course, if your header has more lines, just change head -n1 to head -nX, X being the number of header lines.

    Hope this helps.