Hi there, I'm relatively new to scripting so I would love some help on how to swap two lines in a text file (or move a particular line up or down one line if that works differently). They wouldn't have a consistent line number but a search string particular to each.
So this:
apple
apple
rhubarb
grape
rhubarb
grape
banana
apple
rhubarb
grape
becomes this:
apple
apple
grape
rhubarb
grape
rhubarb
banana
apple
grape
rhubarb
The rhubarb and grape lines have been swapped (or grape has moved up, or rhubarb has moved down). Cheers
Swap/move lines in text file
- dmg
- Posts: 287
- Joined: 02 Oct 2013, 01:43
- Location: "Twelve days north of Hopeless and a few degrees south of Freezing to Death"
- Contact:
Re: Swap/move lines in text file
That should be doable. So, is the ideal goal to be able to feed it a list and a search string and when it finds that string to move it up one line? Or are you really wanting to swap two strings in the list regardless of their relative positions?
"My dear Mr Gyrth, I am never more serious than when I am joking."
~Albert Campion
------------------------------------------------------------------------
Website | Demo scripts | Blog | External contact
~Albert Campion
------------------------------------------------------------------------
Website | Demo scripts | Blog | External contact
Re: Swap/move lines in text file
Hi kiwichick, Welcome to the Ahkscript forum.
fileSwapLines( fileDirectory, line1, line2 )
This function will swap line 1 with line 2 of the file at fileDirectory.
fileSwapLines( fileDirectory, line1, line2 )
This function will swap line 1 with line 2 of the file at fileDirectory.
Code: Select all
fileSwapLines("D:\HTML\css test\style.css", 1, 2 )
fileSwapLines( fileDir, line1, line2 )
{ fileRead, data, % fileDir
FileDelete, % fileDir
fileArray := {}
Loop, Parse, data, `n
fileArray.insert( A_LoopField )
swap := fileArray[ line1 ]
fileArray[ line1 ] := fileArray[ line2 ]
fileArray[ line2 ] := swap
for key, val in fileArray
out .= val "`n"
FileAppend, % out, % fileDir
Return 1
}
Please find me on the IRC if you have any questions, I'm never on the forum anymore.
Re: Swap/move lines in text file
perfect! tested and it swapped as stipulated!
apple1
apple2
rhubarb
grape
rhubarb
grape
banana
apple
rhubarb
grape
apple1
apple2
rhubarb
grape
rhubarb
grape
banana
apple
rhubarb
grape
Last edited by Guest10 on 22 Jan 2014, 23:09, edited 1 time in total.
Re: Swap/move lines in text file
Thank you very muchSjc1000 wrote:Hi kiwichick, Welcome to the Ahkscript forum.
Your code works great but, as you said it swaps the first and second lines, which isn't what I'm after. The lines I want to swap could be any number (they will be consecutive numbers but not consistent numbers) and there will be multiple instances to change.
Re: Swap/move lines in text file
Yes exactly!dmg wrote:So, is the ideal goal to be able to feed it a list and a search string and when it finds that string to move it up one line?
No.dmg wrote:Or are you really wanting to swap two strings in the list regardless of their relative positions?
The two lines will always be consecutive, regardless of where they are in the list, so it doesn't matter if one goes up or one goes down as long as the end result is they swap. But there will always be multiple instances of them (as per the example) so all of them must be changed.
- dmg
- Posts: 287
- Joined: 02 Oct 2013, 01:43
- Location: "Twelve days north of Hopeless and a few degrees south of Freezing to Death"
- Contact:
Re: Swap/move lines in text file
OK! Now that I know what you are after I will see what I can do. It may take a day or two so your patience is appreciated.
"My dear Mr Gyrth, I am never more serious than when I am joking."
~Albert Campion
------------------------------------------------------------------------
Website | Demo scripts | Blog | External contact
~Albert Campion
------------------------------------------------------------------------
Website | Demo scripts | Blog | External contact
- dmg
- Posts: 287
- Joined: 02 Oct 2013, 01:43
- Location: "Twelve days north of Hopeless and a few degrees south of Freezing to Death"
- Contact:
Re: Swap/move lines in text file
Well, so much for it taking a day or two!:
I think this does what you asked for. I implemented it as a function so you should be able to plug the code in with minimal trouble. Supply the function call with the list of words and the word you want to move up one line when found.
I chose to move the word grape up in the list because it avoided an issue with sorting. Moving rhubarb down caused errors because the code would move rhubarb one space ahead, but then it found it again and moved it again.
If it has any trouble or you need help understanding it just post back.
Code: Select all
list :=
(
"apple
apple
rhubarb
grape
rhubarb
grape
banana
apple
rhubarb
grape"
)
msgbox, % list
msgbox, % _upshift(list, "grape")
_upshift(list, line)
{
items := {}
loop, parse, list, `n
{
items.insert(a_loopfield)
}
loop, % items.maxindex()
{
if (items[a_index] = line)
{
items.remove(a_index)
items.insert(a_index - 1, line)
}
}
loop, % items.maxindex()
{
out .= items[a_index] . "`n"
}
return rtrim(out, "`n")
}
I chose to move the word grape up in the list because it avoided an issue with sorting. Moving rhubarb down caused errors because the code would move rhubarb one space ahead, but then it found it again and moved it again.
If it has any trouble or you need help understanding it just post back.
"My dear Mr Gyrth, I am never more serious than when I am joking."
~Albert Campion
------------------------------------------------------------------------
Website | Demo scripts | Blog | External contact
~Albert Campion
------------------------------------------------------------------------
Website | Demo scripts | Blog | External contact
Re: Swap/move lines in text file
i am not sure what the objective for this implementation is but seems to work albeit very confusing. could you re-explain what this script is doing?
Re: Swap/move lines in text file
As I said in my original post, it's just for swapping the order of two sets of lines in a text file. The fruit names in the example are not the literal strings I'm working with. They are strings of code I have exported from one program to use in another but I need to swap the order of particular commands in order to make them work properly in the new program. It would be an ongoing requirement so much easier to do with a script than by handGuest10 wrote:i am not sure what the objective for this implementation is but seems to work albeit very confusing. could you re-explain what this script is doing?
Re: Swap/move lines in text file
Thank you so much, it works great!!! Now I just need to try and modify it for my needs. I'm not very experienced at scripting so it may take me a while. I definitely anticipate returning for more helpdmg wrote:If it has any trouble or you need help understanding it just post back.
- dmg
- Posts: 287
- Joined: 02 Oct 2013, 01:43
- Location: "Twelve days north of Hopeless and a few degrees south of Freezing to Death"
- Contact:
Re: Swap/move lines in text file
Glad it looks like it will work for you! Post back anytime. I will check this thread every now and then, or you can PM me either here or on the other forum:
http://www.autohotkey.com/board/
My user name is dmg on both.
http://www.autohotkey.com/board/
My user name is dmg on both.
"My dear Mr Gyrth, I am never more serious than when I am joking."
~Albert Campion
------------------------------------------------------------------------
Website | Demo scripts | Blog | External contact
~Albert Campion
------------------------------------------------------------------------
Website | Demo scripts | Blog | External contact
Re: Swap/move lines in text file
Yes I posted there as well but I haven't had a reply to my recent update to the post so I tried here.dmg wrote:you can PM me either here or on the other forum:
http://www.autohotkey.com/board/
My user name is dmg on both.
The only problem I immediately have (and I totally knew I'd have trouble with this) is that the list (file contents) isn't static. It will change probably with each use. So I'm guessing I would read the file into a variable and use that. So this:
list :=
(
"apple
apple
...
rhubarb
grape"
)
would become this:
readfile, filecontentsvar, %filetoread%
list :=
(
"filecontentsvar"
)
Am I even in the right ballpark and, if so, how do I make it work because I'm obviously not doing it right? I don't know whether I enclose the variable in %, leave out the "" or what
- Blackholyman
- Posts: 1293
- Joined: 29 Sep 2013, 22:57
- Location: Denmark
- Contact:
Re: Swap/move lines in text file
Code: Select all
readfile, filecontentsvar, %filetoread%
list := filecontentsvar
Courses on AutoHotkey
My Autohotkey Blog
Re: Swap/move lines in text file
Thanks Blackholyman but it didn't work. Just in case you didn't see it, it needs to work with the code that dmg posted above.Blackholyman wrote:or just replace list with filecontentsvar where neededCode: Select all
readfile, filecontentsvar, %filetoread% list := filecontentsvar
- dmg
- Posts: 287
- Joined: 02 Oct 2013, 01:43
- Location: "Twelve days north of Hopeless and a few degrees south of Freezing to Death"
- Contact:
Re: Swap/move lines in text file
You have the basic idea, you just need to understand the syntax. Your code is what we might call pseudo code. It illustrates an idea but is far from being functional. It can be very useful when trying to explain an idea to another scripter.
The command you want is FileRead:
http://auto-hotkey.com/docs/commands/FileRead.htm
It reads the entire contents of a plain text file into a variable to be operated on. I say plain text file simply to mean any fine that contains characters with no formatting info included. (I apologize if I explain something you already know. I have no way of knowing what you understand or don't, so please do not think me condescending)
The portion of my code that contains the list:Is just assigning static text to the list variable. The () are what is called a continuation section, meaning it allows the content on multiple lines to be added to the variable with line breaks in tact. Since you will be using a command to get the var content you don't need that part of the code at all.
Here is my code with the FileRead command added:If you replace the filename parameter with the path to your file, and set the line you want moved, it should work. But even this will only display the changed content in a msgbox. You will probably want to output the changed content to another file, right?
The command you want is FileRead:
http://auto-hotkey.com/docs/commands/FileRead.htm
It reads the entire contents of a plain text file into a variable to be operated on. I say plain text file simply to mean any fine that contains characters with no formatting info included. (I apologize if I explain something you already know. I have no way of knowing what you understand or don't, so please do not think me condescending)
The portion of my code that contains the list:
Code: Select all
list :=
(
"apple
apple
rhubarb
grape
rhubarb
grape
banana
apple
rhubarb
grape"
)
Here is my code with the FileRead command added:
Code: Select all
fileread, list, filename
msgbox, % _upshift(list, "grape")
_upshift(list, line)
{
items := {}
loop, parse, list, `n
{
items.insert(a_loopfield)
}
loop, % items.maxindex()
{
if (items[a_index] = line)
{
items.remove(a_index)
items.insert(a_index - 1, line)
}
}
loop, % items.maxindex()
{
out .= items[a_index] . "`n"
}
return rtrim(out, "`n")
}
"My dear Mr Gyrth, I am never more serious than when I am joking."
~Albert Campion
------------------------------------------------------------------------
Website | Demo scripts | Blog | External contact
~Albert Campion
------------------------------------------------------------------------
Website | Demo scripts | Blog | External contact
Re: Swap/move lines in text file
Yip I actually do understand all of that I certainly do not think you're being condescending And I can see how the code is meant to work but it doesn't. I'm sure it must be something simple I'm doing (like quote marks missing or put around the wrong thing) but I don't know enough to be able to troubleshoot.dmg wrote:You have the basic idea, you just need to understand the syntax. Your code is what we might call pseudo code. It illustrates an idea but is far from being functional. It can be very useful when trying to explain an idea to another scripter.
The command you want is FileRead:
http://auto-hotkey.com/docs/commands/FileRead.htm
It reads the entire contents of a plain text file into a variable to be operated on. I say plain text file simply to mean any fine that contains characters with no formatting info included. (I apologize if I explain something you already know. I have no way of knowing what you understand or don't, so please do not think me condescending)
If you replace the filename parameter with the path to your file, and set the line you want moved, it should work. But even this will only display the changed content in a msgbox. You will probably want to output the changed content to another file, right?
If I use the original code you gave me and type my file contents into the list := (.....) section and change _upshift(list, "grape") to what I want to "shift" (multi-word line), it works fine. I can then also assign the shift to a variable and that works fine too. This works:
Code: Select all
$shift = Gui, 2:Font
list :=
(
"Gui, 2:Add,Text, x272 y24 w227 h193, %$output_sign%
Gui, 2:Add,Picture, x264 y152 w113 h89, %$image_symbol%
Gui, 2:Add,Text, x48 y56 w141 h137, %$output_element%
Gui, 2:Font
Gui, 2:Add,Picture, x680 y32 w201 h193, %$image_planet%
Gui, 2:Add,Text, x712 y56 w141 h137, %$output_planet%
Gui, 2:Font
Gui, 2:Add,Picture, x696 y296 w137 h129, %$image_oppcomp%
Gui, 2:Add,Text, x715 y312 w108 h97, %$output_oppcomp%
Gui, 2:Font
Gui, 2:Add,Button, x408 y472 w97 h41, %$button_close%
Gui, 2:Font
Gui, 2:Show, x184 y104 w906 h563, Trial v2 "
)
msgbox, % list
msgbox, % _upshift(list, $shift)
_upshift(list, line)
{
items := {}
loop, parse, list, `n
{
items.insert(a_loopfield)
}
loop, % items.maxindex()
{
if (items[a_index] = line)
{
items.remove(a_index)
items.insert(a_index - 1, line)
}
}
loop, % items.maxindex()
{
out .= items[a_index] . "`n"
}
return rtrim(out, "`n")
}
Code: Select all
$final = C:\SCRIPTING\AutoHotkey\AstrologistAutoHotkey\final.ahk
$shift = Gui, 2:Font
fileread, list, %$final%
msgbox, % list
msgbox, % _upshift(list, $shift)
_upshift(list, line)
{
items := {}
loop, parse, list, `n
{
items.insert(a_loopfield)
}
loop, % items.maxindex()
{
if (items[a_index] = line)
{
items.remove(a_index)
items.insert(a_index - 1, line)
}
}
loop, % items.maxindex()
{
out .= items[a_index] . "`n"
}
return rtrim(out, "`n")
}
Thank you so much for your patience
Re: Swap/move lines in text file
i hereby testify that i tested as follows and script works as expected and stipulated:
Code: Select all
/*
list :=
(
"apple
apple
rhubarb
grape
rhubarb
grape
banana
apple
rhubarb
grape"
)
*/
fileread, list, list.txt ; list.txt resides in script dir
;fileread, list, list
msgbox, % _upshift(list, "grape")
_upshift(list, line)
{
items := {}
loop, parse, list, `n
{
items.insert(a_loopfield)
}
loop, % items.maxindex()
{
if (items[a_index] = line)
{
items.remove(a_index)
items.insert(a_index - 1, line)
}
}
loop, % items.maxindex()
{
out .= items[a_index] . "`n"
}
return rtrim(out, "`n")
}
dmg wrote:You have the basic idea, you just need to understand the syntax. Your code is what we might call pseudo code. It illustrates an idea but is far from being functional. It can be very useful when trying to explain an idea to another scripter.
The command you want is FileRead:
http://auto-hotkey.com/docs/commands/FileRead.htm
It reads the entire contents of a plain text file into a variable to be operated on. I say plain text file simply to mean any fine that contains characters with no formatting info included. (I apologize if I explain something you already know. I have no way of knowing what you understand or don't, so please do not think me condescending)
The portion of my code that contains the list:Is just assigning static text to the list variable. The () are what is called a continuation section, meaning it allows the content on multiple lines to be added to the variable with line breaks in tact. Since you will be using a command to get the var content you don't need that part of the code at all.Code: Select all
list := ( "apple apple rhubarb grape rhubarb grape banana apple rhubarb grape" )
Here is my code with the FileRead command added:If you replace the filename parameter with the path to your file, and set the line you want moved, it should work. But even this will only display the changed content in a msgbox. You will probably want to output the changed content to another file, right?Code: Select all
fileread, list, filename msgbox, % _upshift(list, "grape") _upshift(list, line) { items := {} loop, parse, list, `n { items.insert(a_loopfield) } loop, % items.maxindex() { if (items[a_index] = line) { items.remove(a_index) items.insert(a_index - 1, line) } } loop, % items.maxindex() { out .= items[a_index] . "`n" } return rtrim(out, "`n") }
- AlphaBravo
- Posts: 586
- Joined: 29 Sep 2013, 22:59
Re: Swap/move lines in text file
Code: Select all
list :=
(
"apple
apple
rhubarb
grape
rhubarb
grape
banana
apple
rhubarb
grape"
)
MsgBox % RegExReplace(list, "s)(.*?)(\V+)(\r?\n)(grape)", "$1$4$3$2")
return
- dmg
- Posts: 287
- Joined: 02 Oct 2013, 01:43
- Location: "Twelve days north of Hopeless and a few degrees south of Freezing to Death"
- Contact:
Re: Swap/move lines in text file
@Guest10:
Thank you kindly for trying it out.
@AlphaBravo:
Thanks for the input but I am pretty sure if kiwichick is having trouble with variables then RegEx may pose an additional challenge...
@kiwichick:
Yikes! I have been over your code several times and I can't find a problem. Everything checks out except the output of the FileRead command. It is getting the file content but for some reason the function I wrote does not work on it correctly. I will play with it some more and trace through the entire thing later. Sorry for the delay, and bear in mind that your code appears to be fine. It is MY code that is misbehaving.
Thank you kindly for trying it out.
@AlphaBravo:
Thanks for the input but I am pretty sure if kiwichick is having trouble with variables then RegEx may pose an additional challenge...
@kiwichick:
Yikes! I have been over your code several times and I can't find a problem. Everything checks out except the output of the FileRead command. It is getting the file content but for some reason the function I wrote does not work on it correctly. I will play with it some more and trace through the entire thing later. Sorry for the delay, and bear in mind that your code appears to be fine. It is MY code that is misbehaving.
"My dear Mr Gyrth, I am never more serious than when I am joking."
~Albert Campion
------------------------------------------------------------------------
Website | Demo scripts | Blog | External contact
~Albert Campion
------------------------------------------------------------------------
Website | Demo scripts | Blog | External contact
Who is online
Users browsing this forum: lechat and 137 guests