Re: codeperl -pe 's/\n/
by ZZamboni (Curate) on May 26, 2000 at 18:13 UTC
|
I'm sure the author will be able to explain it better,
but here it goes:
This makes more sense with an example. Let's say you have the file:
one
two
three
four
And run it through the code above. Here's what happens:
- The "while(<>)" reads "one\n"
- The s substitutes the "\n" in "one\n" with a space
followed by the next line in the file ("two\n"), so $_ now
contains "one two\n".
- The implicit "print" (from the -p option) prints $_.
- Repeat.
--ZZamboni
| [reply] [d/l] [select] |
|
|
while I have no doubt that this is basicaly correct, I'm not convinced that it's 100%
My understanding of the situation is that the regular expression operator iterates over the entire string before it moves on to the "implicit" print. This makes the order
- The "while(<>)" reads "one\n"
- The s substitutes the "\n" in "one\n" with a space followed by the next line in the file ("two\n"), so $_ now contains "one two\n".
- Substitution operator now carries on examining $_, finds \n at the end "one two\n" etc.
- The implicit "print" (from the -p option) prints $_.
If it did the print as step three, surely you would end up with
one two
three four
Update nuance hangs his head in shame :-( I really will have to learn to read posts properly, of course the original node mentions joining pairs of lines. Doh!
As you can all see, my understanding was wrong.
Nuance
Baldrick, you wouldn't see a subtle plan if it painted
itself purple and danced naked on top of a harpsichord,
singing "Subtle plans are here again!"
| [reply] |
|
|
The purpose of the snippet is precisely to
join the lines of the file two at a time. So yes, the output
you give is the one you get, but that is the intended effect.
The -p adds an implicit print at each iteration of the implicit
loop.
| [reply] |
A reply falls below the community's threshold of quality. You may see it by logging in. |
Re: codeperl -pe 's/\n/
by jjhorner (Hermit) on May 26, 2000 at 18:11 UTC
|
Well the /e means to evaluate the right side as an expression.
When you have multiple lines in a text file, each line contains
\n at the end. This is the most common line deliminator. A line
is not defined as whatever is wrapped on your screen, but generally
the space between your \n (newlines).
When you grab a chunk of data using the angle brackets, by
default it defines a chunk as the space between and including the
trailing \n character.
I hope this helps.
J. J. Horner
Linux, Perl, Apache, Stronghold, Unix
jhorner@knoxlug.org http://www.knoxlug.org
| [reply] |
Re: codeperl -pe 's/\n/
by KM (Priest) on May 26, 2000 at 18:24 UTC
|
First, Randal may not have written that line, the primary author on that book is Joeseph Hall.
perl -pe 's/\n/" " . <>/e' data
This is a command line, obviously, and if you read perlrun, you will read that -p will make the assumption that there is a while() loop around your code. So, this would look similar to the following, to Perl:
while (<>) {
s/\n/" " . <>/e;
}
As stated in other responses the /e allows you to be able to evaluate things on the right side of an s///.
2: if data is a filehande and this is a one-liner, how does data get input from a file with "\n"=separated values?
It isn't a filehandle, it is a file name. It get's the the data with \n seperated values because that is what the lines of the file are seperated with. This is not different that opening a file and itterating over it from within a script.
Cheers,
KM | [reply] [d/l] |
|
|
I actually don't recall now whether I wrote it or Joseph did.:)
| [reply] |
|
|
Joseph said you suggested the shiny ball, and that's all you did ;) Just kidding. He never mentioned to me who did what, just gave me some pointers on authoring that came up from when he was working on it.
Cheers,
KM
| [reply] |
Re: codeperl -pe 's/\n/
by swiftone (Curate) on May 26, 2000 at 18:28 UTC
|
The answer to #1 is found in the perlop man page (NOT perlre, suprisingly enough). /e evaluates the right side of a s/// operation. In this example, " " . <> is evaluated rather than treated as a string.
The answer to #2 lies in the <> operator. This is a magic operator that reads the next line of the file mentioned on the command line. The -p has perl loop over the -e'd string until complete, printing (see perlrun man page). So data isn't a filehandle, it's a filename.
| [reply] |