-   Linux - Server (
-   -   Changing the order of rows in multiple blocks in a config file. (

afroresurrection 04-04-2012 12:56 PM

Changing the order of rows in multiple blocks in a config file.
Alright, so let's say I've got this file that has some rows organized into multiple blocks e.g.

# user 1
0. ; jitor
1. [0001](closet-space)
2. secret=pennyRevenge
3. mailbox=0001@default
4. callerid=Jan Itor <555-555-5555>

This repeats for every new user. What I'd like to know is if it's possible to reorganize each block so line 0 is deleted and line 4 moves to the top. The numbers on the side have been added for clarification.

Also, I'm not really looking for a specific solution so much as some tips on how I can script this on my own. Thanks!

jsveiga 04-04-2012 01:57 PM

Hi, there's probably an infinite number of ways to do it, but here's one that you can tailor to your needs;

use warnings;
use strict;
my $blockstartre = qr{^#};
my @outorder = (0, 1, 6, 3, 4, 5, 7);
my @buffer = ();
sub output()
  foreach (@outorder)
      print $buffer[$_]."\n" if ($_ <= $#buffer);
  @buffer = ();
while (<STDIN>)
  output() if (m/$blockstartre/);
  push (@buffer, $_);


Usage: cat origfile | thisscript > newfile
Note that the @outorder specifies the block lines and order you want in the output, considering that 0 is the block start identifier (lines starting with #).

Sorry if I spoiled the fun of scripting it yourself, but there's still plenty of room there for sophistication.


Joao S Veiga

afroresurrection 04-04-2012 04:09 PM

Much obliged, maybe I can salvage some learning experience with this and convert it to python. Would you mind describing to me how you decided to use the buffer and push sections of the script? Is it just through reading perl documentation?

jsveiga 04-05-2012 07:23 AM

Hi, you are welcome;

I used a buffer to be able to switch the lines positions, since you required that a line jumped "up". Like if you receive a bunch of emails, but you need to forward them to someone else in a different sequence: You cannot forward each one upon receiving, but let them sit in your mailbox until you have a complete set to reorder and forward in any desired sequence - hence the buffering. If you only had required that a line was suppressed, no buffering would be required; I'd just count the lines on each block and print/not print out the lines as soon as they were read. Whenever you need to change the order of an input before outputting (for example, doing a "sort") you'll need to hold the information for a while, so a buffer is required.

I don't think this would be in the perl docs; the decision of using a buffer was easy, because I don't know how to do it without it :) - Now, if what you meant to ask was about how do I got to know that perl had the specific capabilities I used (push, array manipulation, etc), then yes, somewhere in the past I got that from reading the perl documentation (which is very good; man perlintro if you want a starting point) and the O'Reilly "Camel" book (and lots of experimenting/trial&error/fun).

Perl was born for this kind of stuff as a "Practical Extraction and Report Language", IMHO, it's the best suited tool for this specific type of task, although of course any language can achieve the same results.


Joao S Veiga

All times are GMT -5. The time now is 09:58 PM.