Forum: Ruby simple one-liners: last line missing

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
Edbb0c681eebfd5c4cdca14492da131d?d=identicon&s=25 Tobi Reif (Guest)
on 2006-03-13 17:48
(Received via mailing list)
Hi

Let's say I'd want to modify each line of a file. Here's the dummy
data:

  $ cat data.txt
  first foo
  second foo
  third foo
  $

This works:

  $ ruby -ne '$_ =~ /(\S+)\s+(\S+)/;puts "#{$2} #{$1}"' data.txt
  foo first
  foo second
  foo third
  $

I don't really need to achieve that modification. Instead I'd like to
understand why the following version one doesn't work:

  $ ruby -pe 'sub(/(\S+)\s+(\S+)/,"#{$2} #{$1}")' data.txt

  foo first
  foo second
  $

TIA,
Tobi
956f185be9eac1760a2a54e287c4c844?d=identicon&s=25 ts (Guest)
on 2006-03-13 18:13
(Received via mailing list)
>>>>> "T" == Tobi Reif <tobiasreif@pinkjuice.com> writes:

T>   $ ruby -pe 'sub(/(\S+)\s+(\S+)/,"#{$2} #{$1}")' data.txt

 The replacement string is build when #sub is called

 for the first call $1 = $2 = nil ==> the replacement string is ' '

 for the second call, $1 = 'first', $2 = 'foo' ==> the replacement
string
 is 'foo first'

 etc,


Guy Decoux
5c841628b56df3a68984986e9f095d01?d=identicon&s=25 Andrew Johnson (andrew)
on 2006-03-13 18:19
(Received via mailing list)
On Tue, 14 Mar 2006 01:46:50 +0900, Tobi Reif <tobiasreif@pinkjuice.com>
wrote:
[snip]
> I don't really need to achieve that modification. Instead I'd like to
> understand why the following version one doesn't work:
>
>   $ ruby -pe 'sub(/(\S+)\s+(\S+)/,"#{$2} #{$1}")' data.txt
>
>   foo first
>   foo second
>   $


When doing substitutions with a string replacement, you do not get what
you might expect because the interpolation of #{$1} in the replacement
string happens when the arguments are evaluated and passed into the
sub()
or gsub() methods, not during the match. That means they will have
whatever
value they had from the last successful match (or nil, as in your case
with
the first line printed).

To access backreferences within a replacement string, you may use the
same
notation as you do for backreferences within the pattern itself: \1, \2,
etc. For your example:

  ruby -pe 'sub(/(\S+)\s+(\S+)/,%q(\2 \1))' data.txt

Alternatively, you may use the block form of replacement, in which case
the
block is evaluated at match-time and $1, $2, etc are available and refer
to
their respective backreferences within the current match:

  ruby -pe 'sub(/(\S+)\s+(\S+)/){"#{$2} #{$1}"}' data.txt

cheer's
andrew
Ce60c4f78a63b0695e4dafc4bd7964f7?d=identicon&s=25 Lou Vanek (Guest)
on 2006-03-13 18:22
(Received via mailing list)
I think you want,

 >ruby -pe 'sub(/(\S+)\s+(\S+)/,"\\2 \\1")' data.txt
Edbb0c681eebfd5c4cdca14492da131d?d=identicon&s=25 Tobi Reif (Guest)
on 2006-03-13 18:28
(Received via mailing list)
On Tue 2006-03-14 ts wrote:
>
>  etc,

Thanks. I guess my (current) opinion is that it should work.

Tobi
Edbb0c681eebfd5c4cdca14492da131d?d=identicon&s=25 Tobi Reif (Guest)
on 2006-03-13 18:40
(Received via mailing list)
On Tue 2006-03-14 Tobi Reif wrote:
> >  is 'foo first'
> >
> >  etc,
>
> Thanks. I guess my (current) opinion is that it should work.
>
> Tobi

Now I understand that it can't work.

Thanks again,
Tobi
This topic is locked and can not be replied to.