I have several las files with a header and each file start Version and text and before the data starts end up with ~Ascii, then the numbers starts:
-------------------------------------------------------------------------
~Version
.....text....
~Ascii
2 abc 230 1 name
1 abc 400 1 name2
3 abb 350 2 name
----------------------------------------------------------------------------
What I want to do is to keep the header as it is and sort with the first column
the result to look something as following :
~Version
.....text....
~Ascii
1 abc 400 1 name2
2 abc 230 1 name
3 abb 350 2 name
and if it is possible to run for all files in one go, since all the files are *.las file?
If you are saying that you want to sort all of the *.las files together into a single output file keeping the header from the 1st file and throwing away the other headers, you could try:
sed -n '1,/~Ascii/p;/~Ascii/q' *.las;sed '/~Version/,/~Ascii/d' *.las|sort -k1,1n
I want to sort each file and the output should be new file for each file.
When I tried the one you post. It doesnot give me output file. And
each new file should keep the header and the data sorted.
Assuming you want to sort the files in place and you don't have any hard links or non-default file modes or group-IDs you need to preserve in your .las files, a simple loop of the cjcox's suggestion should do what you want:
for file in *.las
do sed -n '1,/~Ascii/p;/~Ascii/q' "$file" > "$file.$$" && \
sed '1,/~Ascii/d' "$file" | sort -k1,1n >> "$file.$$" && \
mv "$file.$$" "$file" || rm -f "$file.$$"
done
If you want new files created instead of replacing the original files, try:
for file in *.las
do sed -n '1,/~Ascii/p;/~Ascii/q' "$file" > "$file.new"
sed '1,/~Ascii/d' "$file" | sort -k1,1n >> "$file.new"
done
I'd have to do some benchmarking to see if sed , sed | sort is slower than using awk to invoke sh to invoke sort ; since there are three fork() and exec family (or spawn() ) calls either way; but I like the concept.
Once the file is sorted I am not able to load it to the software I am using .
The reason is that there is a repetition of depth in between (11204 ,11204)
What I want to do is if it find a repetition to add to one of the depth ".1"
the file will look something as following :
How many lines could appear in your input with the same 1st column value. (I assume we need to do something like 11200.01 , 11200.02 , ... 11200.45 rather than 11200.1 , 11200.2 , ... 11200.45 so the program reading your data won't see 11200.1 and 11200.10 as having the same numeric value??? So, the question is how many digits do you need to put after the decimal point to make the number of digits after the decimal constant for the lines that have the same base first field value?
I don't get it... If a number can be repeated in the input no more than three times, why isn't one digit enough?
If a number can be repeated in the input no more than three times, where did 11200.45 come from? Is the above supposed to be input or output? If it is input why are there any decimal points in the 1st field in the input? If it is output, why aren't there decimal points after two of the lines that start with 11632 ?
Are you now saying that the input could have three lines with 11200.45 in the first column and you want the output to be 11200.45 , 11200.45.1 , and 11200.45.2 ? Do you want the output sorted numerically or alphanumerically? (A numeric sort might not work if the strings you're sorting contain more than one decimal point.
Hi
It is enough with one digit decimal. but in some of the files , there is two digit decimal for e.g. in one of the file the first is 11200.45 then the others in the first column is no decimal or in between there is a decimal.. if the file is as following :
the "." is for decimal ...
I do not yet understand how the input you are processing is supposed to be converted into the output you want. Explain what output should be produced by showing us (in CODE tags) the exact output that should be produced for the following input AND by stating the rules (in English) that explain the logic your script is supposed to use to determine why that is the output it should produced from that given input:
11200.45 abc 400 1 name2 original
11200.45 abc 400 1 name2 update 1
11200.45 abc 400 1 name2 update 2
11204 abc 230 1 name
11204 abc 230 1 name
11204 abc 230 1 name
11204.01 abc 230 1 name
11204.01 abc 230 1 name
11204.01 abc 230 1 name
11204.02 abc 230 1 name
11204.02 abc 230 1 name
11204.02 abc 230 1 name
11204.1 abb 350 2 name
11204.1 abb 350 2 name
11204.10 abc 230 1 name
11204.10 abc 230 1 name
11500 abc 400 1 name2
11600 ... .............
11632 .... ..... . ......... original
11632 .... ..... . ......... update 1
11632 .... ..... . ......... update 2
11632.01 .... ..... . ......... original
11632.01 .... ..... . ......... update 1
11632.01 .... ..... . ......... update 2
11632 02 .... ..... . ......... original
11632.02 .... ..... . ......... update 1
11632.02 .... ..... . ......... update 2
11632.1 ..... original
11632.1 ..... update 1
11632.11 .... original
11632.11 .... update 1
11632.2 ... original
11900
12000
If In first column repeats
then the column value + .1, else column.
I have attached two files :
Orginal_las.txt :is the original file unsorted and with some repeating values in column 1.
result_las.txt : is the the result I am looking for, sorted and no repeating values in column 1.
for file in *.las
do
{ # reading from file
# header
while read line
do
echo "$line"
case $line in "~Ascii"*) break;; esac
done
# sort the rest and add number suffix for duplicates
sort -k1,1n |
awk '{if ($1==p1) {sub(" ","."++c)} else {c=0; p1=$1} print}'
} < "$file" > "$file.new"
done
I'm glad that what MadeInGermany suggested is working for you. But, of course, if the 1st line in the sample input you provided in post #9 in this thread:
had another entry with the same decimal value (or if any two lines in your input contained the same value including a decimal point), it just won't work. First the code would try to replace the first two spaces in the on the 2nd matching line with .1 creating (if there were to spaces in that line) 11200.45.1 (which is not a valid decimal number). And, second, if the input can contain decimal values in the 1st column, there is nothing in MadeInGermany's code to detect duplicates created as a result of adding the .1 to the ends of a duplicated line that didn't contain a decimal point.