CGI/Perl Guide | Learning Center | Forums | Advertise | Login
Site Search: in

  Main Index MAIN
INDEX
Search Posts SEARCH
POSTS
Who's Online WHO'S
ONLINE
Log in LOG
IN

Home: Perl Programming Help: Beginner:
Copying a file and modifying line order output

 



Kdawg01
New User

Mar 23, 2013, 4:41 AM

Post #1 of 7 (645 views)
Copying a file and modifying line order output Can't Post

Its been a few years since I've got to play with perl too much and am having some trouble getting exactly what im looking for.

I want to be able to open a txt file and make a new copy but if in the file i find a line that starts with nx00 where the x can be any number to move that line and every line after it to after the next line starting with m6. having trouble with the wildcard for the nx00 line and capturing all the lines in between and outputting correctly. Thanks in advance for any help or advice.

ex:

original file contains:

n700

text 1

text 2

m6

output file:

m6

n700

text 1

text 2


Laurent_R
Veteran / Moderator

Mar 23, 2013, 5:29 AM

Post #2 of 7 (642 views)
Re: [Kdawg01] Copying a file and modifying line order output [In reply to] Can't Post

For detecting the "nx00" line, you can do the following:


Code
print "it is a nx00 line\n" if $line =~ /^n\d+00$/;


Similarly, to detect the "m6" line:


Code
if $(line =~ /^m6/) { # ...



Then, all you have to do is to start storing your lines in an array (or in something else, but an array is the simlplest) when you meet the nx00 line and until you meet the m6 line, and then to dump the array into your file once you've met the M6 line. Nothing complicated.

If you are running into difficulties, please submit the code you've written and explain what does not work as intended.


(This post was edited by Laurent_R on Mar 23, 2013, 5:30 AM)


Chris Charley
User

Mar 23, 2013, 11:06 AM

Post #3 of 7 (633 views)
Re: [Kdawg01] Copying a file and modifying line order output [In reply to] Can't Post

This will do what you are looking for I think.

Code
 #!/usr/bin/perl   
use strict;
use warnings;

while (<DATA>) {
if (/^n\d+00/) {
my $buffer = $_;
while (<DATA>) {
if (/^m6/) {
print;
last;
}
else {
$buffer .= $_;
}
}
print $buffer;
}
else {
print;
}
}

__DATA__
yabba
n7900889ll some more
text 1
text 2
187.231.45.47 - - www.xyz.com 200 10567 www.abc.com
187.231.45.47 - - www.xyz.com 200 10567 www.ab.com
187.231.45.47 - - www.xyz.com 200 10567 www.ab.com
187.231.45.47 - - www.xyz.com 200 10567 www.c.com
187.231.45.47 - - www.x.com 200 10567 www.abc.com
m6 up to here
dabba

Output

Code
  yabba   
m6 up to here
n7900889ll some more
text 1
text 2
187.231.45.47 - - www.xyz.com 200 10567 www.abc.com
187.231.45.47 - - www.xyz.com 200 10567 www.ab.com
187.231.45.47 - - www.xyz.com 200 10567 www.ab.com
187.231.45.47 - - www.xyz.com 200 10567 www.c.com
187.231.45.47 - - www.x.com 200 10567 www.abc.com
dabba

Update: After reading Kenosis's solution, I realized I could have used more illustrative data. That is, would have showed the solution clearer than my data.


(This post was edited by Chris Charley on Mar 23, 2013, 1:23 PM)


Kenosis
User

Mar 23, 2013, 11:57 AM

Post #4 of 7 (626 views)
Re: [Kdawg01] Copying a file and modifying line order output [In reply to] Can't Post

Perhaps the following will be helpful:


Code
use strict; 
use warnings;

my $lines;
while (<>) {
/n\d+00/ and $lines .= $_ and next;
if ( !index $_, 'm6' ) {
print $_, $lines;
$lines = '';
}
elsif ($lines) {
$lines .= $_;
}
else {
print;
}
}


Usage: perl script.pl inFile [>outFile]

Dataset:


Code
text0 
text1
n700
text 1
text 2
m6_foobar
n400
text3_3
text 4
m6_ohmy
n800
text 5
text 6
m6_1234
text3
text4


Output:


Code
text0 
text1
m6_foobar
n700
text 1
text 2
m6_ohmy
n400
text3_3
text 4
m6_1234
n800
text 5
text 6
text3


Use the last, optional argument to redirect output to a file.

Hope this helps!

Edit: Solution's been updated to meet the OP's specs. Thanks, Laurent_R!


(This post was edited by Kenosis on Mar 24, 2013, 12:48 AM)


Laurent_R
Veteran / Moderator

Mar 23, 2013, 3:15 PM

Post #5 of 7 (611 views)
Re: [Kenosis] Copying a file and modifying line order output [In reply to] Can't Post

Hi Kenosis,

your script will work on the data sample that has been given as an example, but I don't think that it fits the description of the problem provided by the OP, which said that lines located between an 'nx00' and an 'm6' line have to be relocated after the 'm6 line. In your script, your are not testing anywhere for the 'nx00' line. Also, your assumption about a line containing non-white characters or not is purely based onthe example, but not on the OP's description of the problem.

Chris Charley's proposal did address the OP's requirement.

I had given some clues to the OP, hoping that she or he would develop something by herself or himself, but since complete solutions have been provided, I might just give mine. This is my quick (and very quickly tested) solution, using a flag ($bufferize) rather than nested loops:


Code
my ($bufferize, $buffer); 
while (<DATA>) {
$bufferize = 1 if /^n\d+00/;
if (/^m6/) {
print $_, $buffer;
$buffer = "";
$bufferize = 0;
next;
}
$buffer .= $_ and next if $bufferize;
print;
}
__DATA__
text0
n700
text 1
text 2
m6_foobar
n400
text3_3
text 4
m6
n800
text 5
text 6
m6


Output:

Code
$ perl  relocate.pl 
text0
m6_foobar
n700
text 1
text 2
m6
n400
text3_3
text 4
m6
n800
text 5
text 6


An additional comment, probably due from the fact that I am working most of the time with files having tens of gigabytes, is that I usually avoid as much as possible to slurp entire files into memory, prefering progressive iteration using almost no memory.

(Of course, this is assuming that sections between an 'nx00' and an 'm6' line are usually relatively short, say a few lines or a few dozens lines, but never tens of millions of lines, otherwise my program might also use a lot of memory, or more complex solutions using for example tied arrays or temporary files.)


(This post was edited by Laurent_R on Mar 23, 2013, 3:29 PM)


Kdawg01
New User

Mar 23, 2013, 3:25 PM

Post #6 of 7 (609 views)
Re: [Kdawg01] Copying a file and modifying line order output [In reply to] Can't Post

Thanks everyone that worked out great i was just trying to way overcomplicate things. Thanks again.


Kenosis
User

Mar 23, 2013, 8:32 PM

Post #7 of 7 (594 views)
Re: [Laurent_R] Copying a file and modifying line order output [In reply to] Can't Post

Hi Laurent_R!

Excellent catch/attention to detail! You're correct: I didn't correctly read the OP's specs. Have updated (and optimized) the script...

Kenosis

 
 


Search for (options) Powered by Gossamer Forum v.1.2.0

Web Applications & Managed Hosting Powered by Gossamer Threads
Visit our Mailing List Archives