Swapping or switching 2 lines using sed


 
Thread Tools Search this Thread
Top Forums Shell Programming and Scripting Swapping or switching 2 lines using sed
# 36  
Old 11-23-2008
At last i manage to solve the mystery. thanx to redouluv. what i'm done, i put close FH outside the while loop so that it capture the new file with new counter line. Smilie. Btw i still need to undestand this script especially the backup & swap cmnd. btw thanx again. glad to learn new things. Smilie

Code:
 perl -e'BEGIN {
  $Pattern = "1012345678";
  $Bak_ext = ".bak";
  #@Files = glob "ABC_DEF*";
 #print "help $i";
  }

@files = <ABC_DEF*>;
  foreach $File (@files) {
  ##checking:print "1\n";
  ##checking:print $File . "\n";
  #$File = $_;
  open FH, $File or die "$File : $!\n";
   while (<FH>)
 {
      ##checking:print "\n2\n";
      ##checking:print "line $. \n" ;
      if($. == 2 && (split)[3] == $Pattern)
     {
          ##checking:print "i'm line 2\n";
          local @ARGV = ($File);
          local $^I = $Bak_ext;
          local $/ = undef;

          while (<>) {
          s/
          \A(.*?\n)
          ((?:\S+\s+){3}$Pattern\b.*?\n)
          (.*?\n)
          /$1$3$2/xos;
          print;
         }
     }
 }close FH;
  ##checking:print "3\n\n";
}'

Rgrds.
# 37  
Old 11-24-2008
Quote:
Originally Posted by null7
[...]
Btw i still need to undestand this script especially the backup & swap cmnd.
[...]

For the backup you could read perlrun/perlvar and search for in-place/INPLACE.
For the regular expression (the swapping) you could read perlre.
# 38  
Old 12-01-2008
Hi I already refer to doc but still blur especially on regexp. Appreciate if u can explain further.

Code:
local @ARGV = ($File); # puts $File into the array @ARGV
local $^I = $Bak_ext;  # (Backup input file, output with original filename)
local $/ = undef;      # read entire file at once

For backup file i think is much easier to understand. but one question is it necessary for us to have this line local $/ = undef;. What will happen if i remove it?

Code:
                          s/   # s/ = substitute operator
                    
                    \A(.*?\n)  # \A = match at only beginning of string
                                # () = grouping
                                # .  = allow single char to match
                                # *? = match 0 or more time
                                # \n = newline
((?:\S+\s+){3}$Pattern\b.*?\n)  # () = grouping
                                # ?: Non-capturing groupings
                                # \S+  Match a non-whitespace character  1 or more times
                                # \s+  Match a whitespace character 1 or more times
                                # {3}= Match exactly 3 times
                                # \b = Match a word boundary
                                # .  = allow single char to match
                                # *? = match 0 or more time
                                # \n = newline
                       (.*?\n)  # .  = allow single char to match
                                # *? = match 0 or more time
                                # \n = newline

                 /$1$3$2/xos;   #substitute with $1$3$2. XOS?

                      print     #print balance line?

For code above, is it correct it do search n replace?(s/regexp/replacement/modifiers). Actually I still blur with the above regexp. Correct me if i'm wrong, is it the regexp match 3 times for the pattern? Smilie. I got confused what exactly it do.
For replacement line, is it $1$3$2 refer to line of the file? i tried to print out $1 to see the content but nothing happened.
I already google for XOS but no explaination about it. Hope someone can help.

Sorry to many question. Smilie

Rgrds.

# 39  
Old 12-02-2008
Quote:
Originally Posted by null7
Hi I already refer to doc but still blur especially on regexp. Appreciate if u can explain further.

Code:
local @ARGV = ($File); # puts $File into the array @ARGV
local $^I = $Bak_ext;  # (Backup input file, output with original filename)
local $/ = undef;      # read entire file at once

For backup file i think is much easier to understand. but one question is it necessary for us to have this line local $/ = undef;. What will happen if i remove it?
If you remove it, you cannot match across lines. Consider the following:

Code:
$ cat file
header
abc  def   ghi   1012345678       500010.00                       
abc  def   ghi   2022222222             10.00 
abc  def   ghi   1022222222             10.00                       
abc  def   ghi   2012345678       500010.00

$ perl -e'BEGIN {
  $Pattern = "1012345678";
  $Bak_ext = ".bak";
  @Files = glob "file*";
  }
for (@Files) {
  $File = $_;
  open FH, $File or die "$File : $!\n";
  while (<FH>) {
    if ($. == 2 and (split)[3] == $Pattern) {
      close FH;
      local @ARGV = ($File);
#      local $^I = $Bak_ext;
#      local $/ = undef;
      while (<>) {
        s/
         \A(.*?\n)
         ((?:\S+\s+){3}$Pattern\b.*?\n)
         (.*?\n)
         /$1$3$2/xos and print;
      }
    }
  }
}'
$ # no output 

$ perl -e'BEGIN {
  $Pattern = "1012345678";
  $Bak_ext = ".bak";
  @Files = glob "file*";
  }
for (@Files) {
  $File = $_;
  open FH, $File or die "$File : $!\n";
  while (<FH>) {
    if ($. == 2 and (split)[3] == $Pattern) {
      close FH;
      local @ARGV = ($File);
#      local $^I = $Bak_ext;
      local $/ = undef; 
      while (<>) {
        s/
         \A(.*?\n)
         ((?:\S+\s+){3}$Pattern\b.*?\n)
         (.*?\n)
         /$1$3$2/xos and print;
      }
    }
  }
}'
header
abc  def   ghi   2022222222             10.00 
abc  def   ghi   1012345678       500010.00                       
abc  def   ghi   1022222222             10.00                       
abc  def   ghi   2012345678       500010.00

Quote:
Code:
                          s/   # s/ = substitute operator
                    
                    \A(.*?\n)  # \A = match at only beginning of string
                                # () = grouping
                                # .  = allow single char to match
                                # *? = match 0 or more time
                                # \n = newline
((?:\S+\s+){3}$Pattern\b.*?\n)  # () = grouping
                                # ?: Non-capturing groupings
                                # \S+  Match a non-whitespace character  1 or more times
                                # \s+  Match a whitespace character 1 or more times
                                # {3}= Match exactly 3 times
                                # \b = Match a word boundary
                                # .  = allow single char to match
                                # *? = match 0 or more time
                                # \n = newline
                       (.*?\n)  # .  = allow single char to match
                                # *? = match 0 or more time
                                # \n = newline

                 /$1$3$2/xos;   #substitute with $1$3$2. XOS?

                      print     #print balance line?

For code above, is it correct it do search n replace?(s/regexp/replacement/modifiers). Actually I still blur with the above regexp. Correct me if i'm wrong, is it the regexp match 3 times for the pattern? Smilie. I got confused what exactly it do.
For replacement line, is it $1$3$2 refer to line of the file? i tried to print out $1 to see the content but nothing happened.
I already google for XOS but no explaination about it. Hope someone can help.

Sorry to many question. Smilie
No problems, we are here to answer your questions.

So:

Code:
 s/                                     #  We can use spaces and newlines here
                                        #+ because of the x modifier (the x from xos). 
         \A(.*?\n)                      #  We can match across lines because ot the undefined
                                        #+ record separator $/. The fist group matches from
                                        #+ the begining of the string to the _first_ newline
                                        #+ (notice the * quantifier is followed by ?, so it's 
                                        #+ not greedy).
                                        #  In this case we don't need it though, if we remove the s
                                        #+ modifier (s from xos) as we don't need that too, we'll
                                        #+ get the expected result with \A(.*\n).                                         
         ((?:\S+\s+){3}$Pattern\b.*?\n) #  Here we are at the second line (i.e. after the first newline).
                                        #  This matches our pattern in the 4th field: 3 times non-spaces
                                        #+ followed by spaces. \b to match the exact pattern and exclude
                                        #+ 10123456780000 for example.                                        
         (.*?\n)                        #  This group matches the next line to be swapped.
         /$1$3$2/xos                    #  Change the order: first group, third, second:
                                        #+ first line, third line, second line.
                                        #  Again: x for legibility. o for compile only once
                                        #+ see perldoc perlreref|less -pOnce.

If I'm not missing something,
the above could be written as:


Code:
s/
  \A(.*\n)
  ((?:\S+\s+){3}$Pattern\b.*\n)
  (.*\n)
/$1$3$2/xo

As you see, there are many errors in the code.

As far as my posts are concerned, these are quick and dirty (sometimes very dirty Smilie) solutions, written without much effort.

You'll need to understand and adjust the code for your needs.


Hope this helps.

Last edited by radoulov; 12-02-2008 at 09:07 AM..
Login or Register to Ask a Question

Previous Thread | Next Thread

10 More Discussions You Might Find Interesting

1. Shell Programming and Scripting

Swapping lines

Hi there, I have a text that I'm trying to format into something more readable. However, I'm stuck in the last step. I've searched and tried things over the internet with no avail. OS: Mac After parsing the original text that I won't put here, I managed to get something like this, but this... (8 Replies)
Discussion started by: Kibou
8 Replies

2. Shell Programming and Scripting

Swapping the 1st 4 lines only

How can you swap the first 4 line only, the rest will stay the same. thanks #!/bin/sh line=4 awk -v var="$line" 'NR==var { s=$0 getline;s=$0"\n"s getline;print;print s next }1' fileko.tx . desired output: (8 Replies)
Discussion started by: invinzin21
8 Replies

3. Shell Programming and Scripting

ksh sed - Extract specific lines with mulitple occurance of interesting lines

Data file example I look for primary and * to isolate the interesting slot number. slot=`sed '/^primary$/,/\*/!d' filename | tail -1 | sed s'/*//' | awk '{print $1" "$2}'` Now I want to get the Touch line for only the associate slot number, in this case, because the asterisk... (2 Replies)
Discussion started by: popeye
2 Replies

4. Shell Programming and Scripting

AWK swapping fields on different lines

Hi All, Sorry if this question has been posted elsewhere, but I'm hoping someone can help me! Bit of an AWK newbie here, but I'm learning (slowly!) I'm trying to cobble a script together that will save me time (is there any other kind?), to swap two fields (one containing whitespace), with... (5 Replies)
Discussion started by: Bravestarr
5 Replies

5. Shell Programming and Scripting

Switching lines

Hi I'm quite new with linux. Very simple, I need to swap every 2 lines in a file. Example INPUT: a a a b b b x x x y y y s s s t t t OUTPUT: b b b a a a y y y x x x t t t (5 Replies)
Discussion started by: hernand
5 Replies

6. Shell Programming and Scripting

Swapping three lines

I have some text: <date>some_date</date> <text>some_text</text> <name>some_name<name> and I want to transform it to smthng like that: some_name on some_date: some_text I've tried sed: sed 's/<text>\(.*\)<\/text> <name>\(.*\)<\/name>/\2 - \1/' but it says unterminated... (13 Replies)
Discussion started by: dsjkvf
13 Replies

7. Homework & Coursework Questions

Swapping Fields with Sed

Use and complete the template provided. The entire template must be completed. If you don't, your post may be deleted! 1. The problem statement, all variables and given/known data: The assignment is to convert a text table to csv format. I've got the cleaning up done, but I need to swap two... (0 Replies)
Discussion started by: VoiceInADesert
0 Replies

8. Shell Programming and Scripting

awk: switching lines and concatenating lines?

Hello, I have only recently begun with awk and need to write this: I have an input consisting of a couple of letters, a space and a number followed by various other characters: fiRcQ 9( ) klsRo 9( ) pause fiRcQ 9( ) pause klsRo continue 1 aPLnJ 62( ) fiRcQ continue 5 ... and so on I... (7 Replies)
Discussion started by: Borghal
7 Replies

9. Shell Programming and Scripting

swapping lines that match a condition using sed, perl or the like

I'm a bit new to regex and sed/perl stuff, so I would like to ask for some advice. I have tried several variations of scripts I've found on the net, but can't seem to get them to work out just right. I have a file with the following information... # Host 1 host 45583 { filename... (4 Replies)
Discussion started by: TheBigAmbulance
4 Replies

10. Shell Programming and Scripting

Swapping lines beginning with certain words using sed/awk

I have a large file which reads like this: fixed-address 192.168.6.6 { hardware ethernet 00:22:64:5b:db:b1; host X; } fixed-address 192.168.6.7 { hardware ethernet 00:22:64:5b:db:b3; host Y; } fixed-address 192.168.6.8 { hardware ethernet 00:22:64:5b:db:b4; host A; }... (4 Replies)
Discussion started by: ksk
4 Replies
Login or Register to Ask a Question