Sign in to follow this  
Followers 0
trademaid

sort space seperated file

28 posts in this topic

#1 ·  Posted (edited)

how do I sort a space separated file?

In the example shown, i want to sort by the second coloumb. ie the 6664.60

100001 6664.60 2 7 9 9 0 2 1 3 5 3 1 14 10 3 8 12 36 90 59 2.0 1.0 1.0 1.0 1.0 1.0 -0.1 -0.8 2.4 -0.5 2.0 2.4 2.9 2.8 -2.8 1.8 2.9 -2.7 -0.9 2.0 0.0 0 0 0 0 3 2 12 8 9 4 1 0 1 2 18

100003 36370.30 2 11 7 1 0 3 1 1 2 3 1 6 12 18 23 4 29 42 92 2.0 1.0 1.0 1.0 1.0 1.0 2.9 -1.9 -0.6 -2.1 0.2 -1.7 -1.9 -1.5 -0.2 0.6 -2.0 -0.1 0.9 1.5 -2.2 0 0 0 0 8 6 4 10 18 4 3 0 1

100012 8683.00 4 8 10 3 0 2 1 5 0 3 1 8 4 16 17 18 15 39 40 2.0 1.0 1.0 1.0 1.0 1.0 1.5 0.0 -0.8 -0.2 0.4 2.5 -2.8 1.5 -0.8 2.0 -2.7 -2.7 -0.3 1.7 1.1 0 0 0 0 10 5 3 16 9 4 3 0 0 10

Edited by trademaid

Share this post


Link to post
Share on other sites



how do I sort a space separated file?

In the example shown, i want to sort by the second coloumb. ie the 6664.60

100001 6664.60 2 7 9 9 0 2 1 3 5 3 1 14 10 3 8 12 36 90 59 2.0 1.0 1.0 1.0 1.0 1.0 -0.1 -0.8 2.4 -0.5 2.0 2.4 2.9 2.8 -2.8 1.8 2.9 -2.7 -0.9 2.0 0.0 0 0 0 0 3 2 12 8 9 4 1 0 1 2 18

100003 36370.30 2 11 7 1 0 3 1 1 2 3 1 6 12 18 23 4 29 42 92 2.0 1.0 1.0 1.0 1.0 1.0 2.9 -1.9 -0.6 -2.1 0.2 -1.7 -1.9 -1.5 -0.2 0.6 -2.0 -0.1 0.9 1.5 -2.2 0 0 0 0 8 6 4 10 18 4 3 0 1

100012 8683.00 4 8 10 3 0 2 1 5 0 3 1 8 4 16 17 18 15 39 40 2.0 1.0 1.0 1.0 1.0 1.0 1.5 0.0 -0.8 -0.2 0.4 2.5 -2.8 1.5 -0.8 2.0 -2.7 -2.7 -0.3 1.7 1.1 0 0 0 0 10 5 3 16 9 4 3 0 0 10

Whether above things corresponds to 3 separate line or not? Is this represent single line.

100001 6664.60 2 7 9 9 0 2 1 3 5 3 1 14 10 3 8 12 36 90 59 2.0 1.0 1.0 1.0 1.0 1.0 -0.1 -0.8 2.4 -0.5 2.0 2.4 2.9 2.8 -2.8 1.8 2.9 -2.7 -0.9 2.0 0.0 0 0 0 0 3 2 12 8 9 4 1 0 1 2 18


[size="4"][font="Arial Narrow"][font="Garamond"]Attitude is a little thing that makes a big difference[/font][/font][/size][indent][/indent]

Share this post


Link to post
Share on other sites

you are correct. what you copied was one line.

Share this post


Link to post
Share on other sites

trademaid,

A bit tortuous, but it gets you there!

#include <Array.au3>

; Load strings
Global $aStrings[3]
$aStrings[0] = "100001 6664.60 2 7 9 9 0 2 1 3 5 3 1 14 10 3 8 12 36 90 59 2.0 1.0 1.0 1.0 1.0 1.0 -0.1 -0.8 2.4 -0.5 2.0 2.4 2.9 2.8 -2.8 1.8 2.9 -2.7 -0.9 2.0 0.0 0 0 0 0 3 2 12 8 9 4 1 0 1 2 18"
$aStrings[1] = "100003 36370.30 2 11 7 1 0 3 1 1 2 3 1 6 12 18 23 4 29 42 92 2.0 1.0 1.0 1.0 1.0 1.0 2.9 -1.9 -0.6 -2.1 0.2 -1.7 -1.9 -1.5 -0.2 0.6 -2.0 -0.1 0.9 1.5 -2.2 0 0 0 0 8 6 4 10 18 4 3 0 1"
$aStrings[2] = "100012 8683.00 4 8 10 3 0 2 1 5 0 3 1 8 4 16 17 18 15 39 40 2.0 1.0 1.0 1.0 1.0 1.0 1.5 0.0 -0.8 -0.2 0.4 2.5 -2.8 1.5 -0.8 2.0 -2.7 -2.7 -0.3 1.7 1.1 0 0 0 0 10 5 3 16 9 4 3 0 0 10"

; Create an array to hold the elements to sort
Global $aSorter[UBound($aStrings)][2]
; Load the eleents to sort and remember which string they came from
For $i = 0 To UBound($aStrings) - 1
    $aTemp = StringSplit($aStrings[$i], " ")
    $aSorter[$i][0] = Number($aTemp[2])
    $aSorter[$i][1] = $i
Next

_ArrayDisplay($aSorter)

; Sort the array
_ArraySort($aSorter)

_ArrayDisplay($aSorter)

; Creat a new array to hold the sorted strings
Global $aNewStrings[UBound($aStrings)]
; Move through the array filling it with strings from the original array in sorted order
For $i = 0 To UBound($aStrings) - 1
    $aNewStrings[$i] = $aStrings[$aSorter[$i][1]]
Next

; Voila!
_ArrayDisplay($aNewStrings)

I have left the _ArrayDisplay lines in so you can see what is going on - you can delete them when you no longer need them.

M23


Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind._______My UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Share this post


Link to post
Share on other sites

#5 ·  Posted (edited)

a big thank you. I got stuck reading the file into the array.

got an error 1

#include <file.au3>
Dim $aRecords
$fname="C:\1.txt"
If Not _FileReadToArray("$fname",$aRecords) Then
   MsgBox(4096,"Error", " Error reading log to Array     error:" & @error)
   Exit
EndIf
For $x = 1 to $aRecords[0]
    Msgbox(0,'Record:' & $x, $aRecords[$x])
Next
Edited by trademaid

Share this post


Link to post
Share on other sites

trademaid,

Remove the "" from this line:

_FileReadToArray("$fname",$aRecords)

Once you have declared the variable you do not need the "". Of course, if you use the literal string like this:

_FileReadToArray("C:\1.txt",$aRecords)

then you do.

Understood?

M23


Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind._______My UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Share this post


Link to post
Share on other sites

#7 ·  Posted (edited)

Thanks for the "" tip. I blame lack of sleep for not picking that one.

i now get sortgrail.au3 (28) : ==> Array variable has incorrect number of subscripts or subscript dimension range exceeded.:

i include 0.txt and 1.txt. Note that the first 4 lines had been removed in my testing. this is file 0.txt

file 1.txt has 4 other lines I dont want sorted. Sorting this file is my end goal.

#include <file.au3>
#include <Array.au3> ; Load strings Global $aStrings[3]
Dim $aStrings
$fname = "C:\0.txt"
;#comments-start
If Not _FileReadToArray($fname, $aStrings) Then
    MsgBox(4096, "Error", " Error reading log to Array     error:" & @error)
    Exit
EndIf
For $x = 1 To $aStrings[0]
MsgBox(0, 'Record:' & $x, $aStrings[$x])
Next

;msgbox(1,"1",$aStrings[1])
;msgbox(1,"2",$aStrings[2])
;msgbox(1,"3",$aStrings[3])

;#comments-end
global $aStrings[3]
;$aStrings[0] = "100001 6664.60 2 7 9 9 0 2 1 3 5 3 1 14 10 3 8 12 36 90 59 2.0 1.0 1.0 1.0 1.0 1.0 -0.1 -0.8 2.4 -0.5 2.0 2.4 2.9 2.8 -2.8 1.8 2.9 -2.7 -0.9 2.0 0.0 0 0 0 0 3 2 12 8 9 4 1 0 1 2 18"
;$aStrings[1] = "100003 36370.30 2 11 7 1 0 3 1 1 2 3 1 6 12 18 23 4 29 42 92 2.0 1.0 1.0 1.0 1.0 1.0 2.9 -1.9 -0.6 -2.1 0.2 -1.7 -1.9 -1.5 -0.2 0.6 -2.0 -0.1 0.9 1.5 -2.2 0 0 0 0 8 6 4 10 18 4 3 0 1"
;$aStrings[2] = "100012 8683.00 4 8 10 3 0 2 1 5 0 3 1 8 4 16 17 18 15 39 40 2.0 1.0 1.0 1.0 1.0 1.0 1.5 0.0 -0.8 -0.2 0.4 2.5 -2.8 1.5 -0.8 2.0 -2.7 -2.7 -0.3 1.7 1.1 0 0 0 0 10 5 3 16 9 4 3 0 0 10"
; Create an array to hold the elements to sort
Global $aSorter[UBound($aStrings)][2]
; Load the eleents to sort and remember which string they came from
For $i = 1 To UBound($aStrings) - 1
    $aTemp = StringSplit($aStrings[$i], " ")
    $aSorter[$i][0] = Number($aTemp[2])  ;************ this is line 28 that gives the error ***************
    $aSorter[$i][1] = $i
Next
_ArrayDisplay($aSorter) ; Sort the array
_ArraySort($aSorter)
_ArrayDisplay($aSorter)
; Creat a new array to hold the sorted strings
Global $aNewStrings[UBound($aStrings)]
; Move through the array filling it with strings from the original array in sorted order
For $i = 0 To UBound($aStrings) - 1
    $aNewStrings[$i] = $aStrings[$aSorter[$i][1]]
Next
; Voila! 
_ArrayDisplay($aNewStrings);### Tidy Error -> for is never closed in your script.

0.txt

1.txt

Edited by trademaid

Share this post


Link to post
Share on other sites

#8 ·  Posted (edited)

Hi

#include <Array.au3>

Global $sInFile = @ScriptDir & "\0.txt"
Global $aStr, $aSort, $SS1

;read file to array
If FileExists($sInFile) Then
    $aStr = StringSplit(StringStripCR(StringStripWS(FileRead($sInFile), 3)), @LF, 2)
Else
    MsgBox(4096, "Error", "No file found")
    Exit
EndIf
_ArrayDisplay($aStr, "$aStr before sorting")

;create new 2d array for sorting
Dim $aSort[UBound($aStr)][2]
For $i = 0 To UBound($aStr) - 1
    $SS1 = StringSplit($aStr[$i], "  ", 3)
    $aSort[$i][0] = Number($SS1[1])
    $aSort[$i][1] = $aStr[$i]
Next
_ArrayDisplay($aSort, "$aSort before sorting")
_ArraySort($aSort)
_ArrayDisplay($aSort, "$aSort after sorting")

;convert the sorted 2d array back to the original 1D array
For $i = 0 To UBound($aSort) - 1
    $aStr[$i] = $aSort[$i][1]
Next
_ArrayDisplay($aStr, "$aStr after sorting")

Cheers

Edited by smashly

Share this post


Link to post
Share on other sites

Hi Smashly,

thats an impressive improvement and it all works.

if i use 4.txt with the first 4 lines these are not stripped out of the search, and the script fails if it finds them.

thats what I thought the "3" in "$aStr = StringSplit(StringStripCR(StringStripWS(FileRead($sInFile), 3)), @LF, 2)" was for.

The last tricky part in the code is I need to delete any lines in the array that have duplicate values.

ie in 4.txt there are two coulombs with 12947.50. I am only concerned with duplicates on the second coloumb.

ps how do i put autoit code in the forums with the [autoit] brackets before hand and after?

4.txt

Share this post


Link to post
Share on other sites

#10 ·  Posted (edited)

Hi,

Sorry re-read your post, missed the part about dups by the sortng number..

Will post again soon

Cheers

Edited by smashly

Share this post


Link to post
Share on other sites

#11 ·  Posted (edited)

Your script did not work perfectly.

the duplicates arnt removed, see sort.png

I then need to write the array to another filename. This file should have the first four lines at the start.

any ideas?

post-34520-12542939994072_thumb.png

Edited by trademaid

Share this post


Link to post
Share on other sites

Hi,

Think I got it sorted, maybe

#include <Array.au3>

Global $sInFile = @ScriptDir & "\4.txt"
Global $aStr, $aSort, $aSS1, $sTmp, $sRet

;read file to array
If FileExists($sInFile) Then
    $aStr = StringSplit(StringStripCR(StringStripWS(FileRead($sInFile), 3)), @LF, 2)
Else
    MsgBox(4096, "Error", " Error reading file to Array error:" & @error)
    Exit
EndIf
_ArrayDisplay($aStr, "$aStr before sorting")

;create new 2d array for sorting
Dim $aSort[UBound($aStr) - 4][2]
For $i = 0 To UBound($aSort, 1) - 1
    If $i < 4 Then $sRet &= $aStr[$i] & @LF
    $aSS1 = StringSplit($aStr[$i + 4], "  ", 3)
    $aSort[$i][0] = Number($aSS1[1])
    $aSort[$i][1] = $aStr[$i + 4]
Next
_ArrayDisplay($aSort, "$aSort before sorting")
_ArraySort($aSort)
_ArrayDisplay($aSort, "$aSort after sorting, dups not removed yet")

;convert the sorted 2d array back to the original 1D array and romove duplicate lines based on matching sorting numbers
For $i = 0 To UBound($aSort) - 1
    If Not StringInStr($sTmp, $aSort[$i][0]) Then
        $sTmp &= $aSort[$i][0] & @LF
        $sRet &= $aSort[$i][1] & @LF
    EndIf
Next
$aStr = StringSplit(StringStripWS($sRet, 2), @LF, 2)
_ArrayDisplay($aStr, "$aStr after sorting and removing duplicate lines")

Cheers

Share this post


Link to post
Share on other sites

#13 ·  Posted (edited)

fixed :D

how to i outout the array to a file?

Edited by trademaid

Share this post


Link to post
Share on other sites

#14 ·  Posted (edited)

Hi again,

Here's a version of the same code writing to a new file

#include <Array.au3>

Global $sInFile = @ScriptDir & "\4.txt"
Global $OutFile = @ScriptDir & "\4_Sorted.txt"
Global $aStr, $aSort, $aSS1, $sTmp, $sRet

;read file to array
If FileExists($sInFile) Then
    $aStr = StringSplit(StringStripCR(StringStripWS(FileRead($sInFile), 3)), @LF, 2)
Else
    MsgBox(4096, "Error", " Error reading file to Array error:" & @error)
    Exit
EndIf

;create new 2d array for sorting
Dim $aSort[UBound($aStr) - 4][2]
For $i = 0 To UBound($aSort, 1) - 1
    If $i < 4 Then $sRet &= $aStr[$i] & @CRLF
    $aSS1 = StringSplit($aStr[$i + 4], "  ", 3)
    $aSort[$i][0] = Number($aSS1[1])
    $aSort[$i][1] = $aStr[$i + 4]
Next

_ArraySort($aSort)

;convert the sorted 2d array back to the original 1D array and romove duplicate lines based on matching sorting numbers
For $i = 0 To UBound($aSort) - 1
    If Not StringInStr($sTmp, $aSort[$i][0]) Then
        $sTmp &= $aSort[$i][0] & @LF
        $sRet &= $aSort[$i][1] & @CRLF
    EndIf
Next
FileWrite($OutFile, $sRet)

Cheers

PS. This works for me based on your 4.txt..

14 lines in

13 lines out

No Dups based on the sorting number.

Edited by smashly

Share this post


Link to post
Share on other sites

thank you all.

works but im getting issues on some files

this line gives "$aSort[$i][0] = Number($aSS1[1])"

Array variable has incorrect number of subscripts or subscript dimension range exceeded.:

any clues?

Share this post


Link to post
Share on other sites

Here is another similar method that works.

;
#include <Array.au3>

Local $aArray, $sStr, $sRet
Local $sFileName = "4.txt" ; From:-   [url="http://www.autoitscript.com/forum/index.php?showtopic=103151&view=findpost&p=731383"]http://www.autoitscript.com/forum/index....?showtopic=103151&view=findpost&p=731383[/url]

If FileExists($sFileName) Then
    Local $sStringFile = FileRead($sFileName)
Else
    Exit
EndIf
Local $sStrHeader = StringRegExpReplace($sStringFile, "(?m)((^.*\v+|\v+){4})(?s)(.*)", "\1") ; Return string up to line no. 0-based.
;ConsoleWrite($sStrHeader & @CRLF)

Local $sString = StringRegExpReplace(StringStripWS($sStringFile, 2), "(?m)(?:(?:^.*\v+|\v+){3})(?:^.*\v+)(?s)(.*)", "\1") ; Return string all above  line no. 0-based. line
;ConsoleWrite($sString & @CRLF)

;Copy second column in line and add to beginning of that line with a "#" (eg. 6664.60#100001 6664.60 2 7 ...) All lines.
Local $sStr = StringRegExpReplace($sString, "(\d+) +(\d*\.*\d*) +(.+\v*|$)", "\2#\1 \2 \3") ; <- Will sort on 2nd column.
;ConsoleWrite(StringRegExpReplace($sString, "(\d+) +(\d*\.*\d*) +(.+\v*|$)", "\2 ") & @CRLF)

$aArray = StringSplit($sStr, @CRLF, 1)
For $x = 1 To UBound($aArray) - 1
    $aArray[$x] = StringFormat("%09s", StringRegExpReplace($aArray[$x], "(.*)(#.+\v*)", "\1"), "") & "#" & _
            StringRegExpReplace($aArray[$x], "(?:.*#)(.+\v*)", "\1")
    ;ConsoleWrite($aArray[$x] & @CRLF)
Next
;_ArrayDisplay($aArray)

_ArraySort($aArray, 0, 1, 0, 0); 2nd parameter, first "0" sorts ascendingly. Change to "1" to sorts 2nd column of data descendingly

; Remove duplicates and remove previously added 2nd column prefix from all lines and convert back to a string.
$sRet = StringRegExpReplace($aArray[1], "^(.+#)", "") & @CRLF
For $x = 2 To UBound($aArray) - 1
    ;ConsoleWrite(StringRegExpReplace($aArray[$x-1], "^(.+)#(.+\v*|$)", "\1") & @CRLF)
    If StringRegExpReplace($aArray[$x - 1], "^(.+)#(.+\v*|$)", "\1") <> StringRegExpReplace($aArray[$x], "^(.+)#(.+\v*|$)", "\1") Then _ ; If not duplicate then
            $sRet &= StringRegExpReplace($aArray[$x], "^(.+#)", "") & @CRLF
Next
$sRet = $sStrHeader & $sRet
;ConsoleWrite($sRet & @CRLF)
Local $iMsg = MsgBox(4, "Result", $sRet & @CRLF & @CRLF & 'Press Yes to save and replace existing "' & $sFileName & _
        '" file with above data, or' & @CRLF & "Press No to exit.")
If $iMsg = 6 Then
    $hFile = FileOpen($sFileName, 2)
    FileWrite($hFile, $sRet)
    FileClose($hFile)
    Run('notepad.exe ' & @ScriptDir & "\" & $sFileName)
EndIf
;

Share this post


Link to post
Share on other sites

the problem is a data issue.

see end of file.

im not sure how to filter this out.

it seems among other things a crlf is missing in the file

bad.txt

Share this post


Link to post
Share on other sites

#18 ·  Posted (edited)

the problem is a data issue.

see end of file.

im not sure how to filter this out.

it seems among other things a crlf is missing in the file

Hi,

As a cheap work around I added a filter that checks if a line at least has a double space, if it doesn't then just drop the line all together.

This will at least stop the "$aSort[$i][0] = Number($aSS1[1])" error on a bad file.

your bad.txt in 2390 lines

Bad_Sorted.txt out 648 lines

#include <Array.au3>

Global $sInFile = @ScriptDir & "\bad.txt"
Global $OutFile = @ScriptDir & "\Bad_Sorted.txt"
Global $aStr, $aSort, $aSS1, $sTmp, $sRet

;read file to array
If FileExists($sInFile) Then
    $aStr = StringSplit(StringStripCR(StringStripWS(FileRead($sInFile), 3)), @LF, 2)
Else
    MsgBox(4096, "Error", " Error reading file to Array error:" & @error)
    Exit
EndIf

;Filter out a line if it doesn't have a double space.
;Sorta getting beyond a joke, next it'll be "ohh, but sometimes a file is like this or that...", bahhh :P
For $i = 0 To UBound($aStr) - 1
    If StringInStr($aStr[$i], "  ") Or $i < 4 Then $sTmp &= $aStr[$i] & @LF
Next
$aStr = StringSplit(StringStripWS($sTmp, 2), @LF, 2)
$sTmp = ''

;create new 2d array for sorting
Dim $aSort[UBound($aStr) - 4][2]
For $i = 0 To UBound($aSort, 1) - 1
    If $i < 4 Then $sRet &= $aStr[$i] & @CRLF
    $aSS1 = StringSplit($aStr[$i + 4], "  ", 3)
    $aSort[$i][0] = Number($aSS1[1])
    $aSort[$i][1] = $aStr[$i + 4]
Next
_ArraySort($aSort)

;convert the sorted 2d array into a sring and remove duplicate lines based on matching sorting numbers
For $i = 0 To UBound($aSort) - 1
    If Not StringInStr($sTmp, $aSort[$i][0]) Then
        $sTmp &= $aSort[$i][0] & @LF
        $sRet &= $aSort[$i][1] & @CRLF
    EndIf
Next
FileWrite($OutFile, StringStripWS($sRet, 2))

Are the first numbers of a line always 6 digits long or does that length vary?

It would probably be better if you could check if a line has a double space at an exact position in the line, this way there'd be less chance of writing dud lines to the new file.

Cheers

Edited by smashly

Share this post


Link to post
Share on other sites

im trying to clean the data

whats wrong with

if (StringLen($line) <> 633 and StringLen($line) <320 and StringLen($line) >300 )then MsgBox(0, "Line read:" & StringLen($line), $line)

only the first logical command is evaluated. ie the 644, not the 320 and 300

Share this post


Link to post
Share on other sites

im trying to clean the data

whats wrong with

if (StringLen($line) <> 633 and StringLen($line) <320 and StringLen($line) >300 )then MsgBox(0, "Line read:" & StringLen($line), $line)

only the first logical command is evaluated. ie the 644, not the 320 and 300

If the number of characters in the string, $line has less than 320 characters and greater than 300 characters the MsgBox should display.

;
$line = "1234567890123456789012345678901" ; 31 characters 
if (StringLen($line) <> 63 and   StringLen($line) <32  and   StringLen($line) >30  )then MsgBox(0, "Line read: " & StringLen($line), $line)
;

Here is a hybrid method from Melba23, smashly, and myself.

;
;#include <Array.au3>

_FileSort("4.txt", "4Mod.txt", 0, 1, 4, 2, 1, 1) ; From:-   [url="http://www.autoitscript.com/forum/index.php?showtopic=103151&view=findpost&p=731383"]http://www.autoitscript.com/forum/index....?showtopic=103151&view=findpost&p=731383[/url]

Run('notepad.exe ' & @ScriptDir & "\4Mod.txt")

;Parameters:-
;$iDescending      - For descending order set $iDescending to a numeric value not zero.
;$iNumbers        - To sort numbers set $iNumbers to a numeric value not zero.
;$iStartSortLine - Start sorting at this line number. First line is line number zero.
;$iColumn        - First word is column 1, space/s, 2nd word  is column 2, space/s, next word is next column,space/s, etc.
;$RemoveDuplic     - "1" removes lines with duplicate $iColumn data. "0" will not remone any lines.
;$FilterData       - "1" removes lines which do not have the same number of words as the $iStartSortLine line. "0" for no filtering of data.
;
Func _FileSort($sFileIn, $sFileOut, $iDescending = 0, $iNumbers = 0, $iStartSortLine = 0, $iColumn = 0, $RemoveDuplic = 0, $FilterData = 0)
    Local $aArray, $sStr, $sRet, $iReplacements, $CheckReplac
    If FileExists($sFileIn) Then
        Local $sStringFile = FileRead($sFileIn)
    Else
        MsgBox(4096, "Error", " File does not exist")
        Exit
    EndIf
    $aArray = StringSplit(StringStripWS($sStringFile, 2), @CRLF, 3)
    ;_ArrayDisplay($aArray)

    ;=========== Filtering of data ===========================
    If $FilterData = 1 Then
        Local $aTempArray[UBound($aArray)], $iNum = $iStartSortLine - 1
        ;Add header & 1st/top lines to $aTempArray.
        For $x = 0 To $iStartSortLine - 1
            $aTempArray[$x] = $aArray[$x]
        Next
        StringRegExpReplace($aArray[$iStartSortLine] & " ", "(\S+)\s+", "(\\S+)\\s+")
        $iReplacements = @extended ; No. of words on line $iStartSortLine
        ;ConsoleWrite($iReplacements & @CRLF)
        For $x = $iStartSortLine To UBound($aArray) - 1
            StringRegExpReplace($aArray[$x] & " ", "(\S+)\s+", "(\\S+)\\s+")
            $CheckReplac = @extended ; ; No. of words on line.
            If $CheckReplac = $iReplacements Then
                $iNum += 1
                $aTempArray[$iNum] = $aArray[$x]
            EndIf
        Next
        ReDim $aTempArray[$iNum + 1]
        $aArray = $aTempArray
    EndIf
    ;_ArrayDisplay($aArray)
    ;===========> End of Filtering of data ======================

    Local $aColFile[UBound($aArray)][2], $aTemp, $aSwapTemp0, $aSwapTemp1, $bPass = False
    For $x = $iStartSortLine To UBound($aArray) - 1
        If $aArray[$x] <> "" Then
            $aTemp = StringSplit(StringRegExpReplace($aArray[$x], StringTrimRight(StringRegExpReplace($aArray[$x] & " ", "(\S+)\s+", "(\\S+)\\s+"), 3), "\" & $iColumn & "#" & $aArray[$x]), "#", 3)
            $aColFile[$x][0] = $aTemp[0] ; column to sort on
            $aColFile[$x][1] = $x ; index of array, $aArray.
        EndIf
    Next
    ;_ArrayDisplay($aColFile)

    ; Sort Array, $aColFile, on the added 1st column. 2nd column being index of line line in array, $aArray.
    While Not $bPass
        $bPass = True
        For $x = $iStartSortLine To UBound($aColFile) - 2
            If ($iNumbers <> 0 And $iDescending = 0 And Number($aColFile[$x][0]) > Number($aColFile[$x + 1][0])) Or _
                    ($iNumbers = 0 And $iDescending = 0 And $aColFile[$x][0] > $aColFile[$x + 1][0]) Or _
                    ($iNumbers <> 0 And $iDescending <> 0 And Number($aColFile[$x][0]) < Number($aColFile[$x + 1][0])) Or _
                    ($iNumbers = 0 And $iDescending <> 0 And $aColFile[$x][0] < $aColFile[$x + 1][0]) Then
                $aSwapTemp0 = $aColFile[$x][0]
                $aSwapTemp1 = $aColFile[$x][1]
                $aColFile[$x][0] = $aColFile[$x + 1][0]
                $aColFile[$x][1] = $aColFile[$x + 1][1]
                $aColFile[$x + 1][0] = $aSwapTemp0
                $aColFile[$x + 1][1] = $aSwapTemp1
                $bPass = False
            EndIf
        Next
    WEnd
    ;_ArrayDisplay($aColFile)

    ;Header & 1st/top line sorted
    For $x = 0 To $iStartSortLine - 1
        $sRet &= $aArray[$x] & @CRLF
    Next
    $sRet &= $aArray[$aColFile[$iStartSortLine][1]] & @CRLF
    ; Remove duplicates and remove previously added column prefix from all lines and convert back to a string.
    For $x = $iStartSortLine + 1 To UBound($aColFile) - 1
        If $RemoveDuplic = 1 And $aColFile[$x - 1][0] <> $aColFile[$x][0] Then $sRet &= $aArray[$aColFile[$x][1]] & @CRLF
        If $RemoveDuplic <> 1 Then $sRet &= $aArray[$aColFile[$x][1]] & @CRLF
    Next

    ;Write $sRet to $sFileOut, file.
    $hFile = FileOpen($sFileOut, 2)
    FileWrite($hFile, $sRet)
    FileClose($hFile)
EndFunc   ;==>_FileSort
;

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0