# Switch Two Lines in a File

**URL:** <https://www.ruby-forum.com/t/switch-two-lines-in-a-file/137517>\
**Category:** Ruby\
**Created:** [May 13, 2008, 10:32pm UTC](https://www.ruby-forum.com/t/switch-two-lines-in-a-file/137517 "2008-05-13T22:32:16Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![Dana\_M](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/edb3f5/32.png) [@Dana\_M](https://www.ruby-forum.com/u/Dana_M)\
**Post date:** [May 13, 2008, 10:32pm UTC](https://www.ruby-forum.com/t/switch-two-lines-in-a-file/137517/1 "2008-05-13T22:32:16Z")

</div>

Hey guys,

I’m trying to write a script to switch two lines in a file, and for some  
reason am having difficulty grokking it.

I have an ugly start, which I’ll post if you want, but it’s over thirty  
lines long and still doesn’t work. I’m sure there is a very short, very  
simple, very Ruby solution to this, and I’m sure one of you has it.

So I’m going to cheat and ask you guys.

Any ideas?

-Dana

---

<div class="post-metadata">

**Author:** ![Dana\_M](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/edb3f5/32.png) [@Dana\_M](https://www.ruby-forum.com/u/Dana_M)\
**Post date:** [May 13, 2008, 10:38pm UTC](https://www.ruby-forum.com/t/switch-two-lines-in-a-file/137517/2 "2008-05-13T22:38:44Z")

</div>

Oh, sorry, I should have mentioned, I’m providing two regexes, and the  
script is to replace a line that matches one regex with a line that  
matches the other.

I.E.  
line one  
line two  
line three

a=/one/  
b=/three/

And the script produces:  
line three  
line two  
line one

I intend on passing it robust enough regexes that they only match a  
single line (i.e. not /line/).

-Dana

---

<div class="post-metadata">

**Author:** ![Dana\_M](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/edb3f5/32.png) [@Dana\_M](https://www.ruby-forum.com/u/Dana_M)\
**Post date:** [May 13, 2008, 11:39pm UTC](https://www.ruby-forum.com/t/switch-two-lines-in-a-file/137517/3 "2008-05-13T23:39:27Z")

</div>

On 5/13/08, Dana M. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> b=/three/
> 
> > 
> 
> Dana M. - System A.  
> Integrated Computer Solutions, Inc.  
> 54B Middlesex Tpke, Bedford, MA 01730  
> 617.621.0060 x112 - [http://www.ics.com](http://www.ics.com)

one somewhat inefficient possibility is:

f= File.new(fname,File::RDWR)  
lines=f.readlines  
first = lines.index(lines.grep(/p1/)[0])  
second = lines.index(lines.grep(/p2/)[0])  
lines[first],lines[second]=lines[second],lines[first]  
f.rewind  
f.write lines  
f.close

---

<div class="post-metadata">

**Author:** ![Dana\_M](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/edb3f5/32.png) [@Dana\_M](https://www.ruby-forum.com/u/Dana_M)\
**Post date:** [May 14, 2008, 12:07am UTC](https://www.ruby-forum.com/t/switch-two-lines-in-a-file/137517/4 "2008-05-14T00:07:59Z")

</div>

Dana M. wrote:

> I’m providing two regexes, and the  
> script is to replace a line that matches one regex with a line that  
> matches the other.

Here’s my solution; thanks for the fun exercise.

$ cat foo  
line three  
line two  
line one  
another one  
another three

$ ruby -v switch.rb foo  
ruby 1.8.6 (2007-09-24 patchlevel 111) [i686-linux]  
line one  
line two  
line three  
another three  
another one

$ cat switch.rb  
firstQuery = /one/  
secondQuery = /three/

# determine line numbers of matching lines

firstIndices = []  
secondIndices = []

lines = ARGF.readlines  
lines.each\_with\_index do |line, i|  
case line  
when firstQuery  
firstIndices \<\< i  
when secondQuery  
secondIndices \<\< i  
end  
end

# swap all matching lines

firstIndices.zip(secondIndices).each do |(a, b)|  
lines[a], lines[b] = lines[b], lines[a]  
end

puts lines
