Shell problem: How to change text in a line depending on data in the following line.

Shell problem: How to change text in a line depending on data in the following line.

Post by Viggo Sk » Sat, 18 May 1996 04:00:00



Hi,

Basicly a simple problem, but more complex in UNIX-Shell programming.

File:
122331133XX
11   11  11
22244422233323
werrwr
weer4213131e2XX
11  1     11  1
2341123XX
11  1
2422
424211
24dwq4
End of file

I have to change text in a file like the one above.

1. Changes is to be done only to lines ending with XX.
2. All '1' should be changed to '2', but only if the same position on
the next line is '1'.
3. All '13' should be changes to '99', but only if the same positions
on the next line is ' 1'.

I have to solve the problem using standard UNIX, so perl is not an
option.

All ideas would be appreciated.

Brgds

Viggo Skov

 
 
 

Shell problem: How to change text in a line depending on data in the following line.

Post by Patrice Alla » Tue, 21 May 1996 04:00:00



>1. Changes is to be done only to lines ending with XX.
>2. All '1' should be changed to '2', but only if the same position on
>the next line is '1'.
>3. All '13' should be changes to '99', but only if the same positions
>on the next line is ' 1'.

I think awk (called nawk on some system to refer to the new awk) is a
good tool for that purpose (unless you consider awk as non standard
UNIX). It doesn't have all the features of perl but quite enough to do
the job.

Hope this helps,
Patrice.
---------------------------------------------------------------------

|  #include <disclaimer.h>  |   V-mail : (+33) 92 29 39 49 + 3902   |
|-------------------------------------------------------------------|

 
 
 

Shell problem: How to change text in a line depending on data in the following line.

Post by Heiner Stev » Tue, 21 May 1996 04:00:00


 > Basicly a simple problem, but more complex in UNIX-Shell
 > programming.

 > File:
 > 122331133XX
 > 11   11  11
 > 22244422233323
 > werrwr
 > weer4213131e2XX
 > 11  1     11  1
 > 2341123XX
 > 11  1
 > 2422
 > 424211
 > 24dwq4
 > End of file

 > I have to change text in a file like the one above.
 > 1. Changes is to be done only to lines ending with XX.
 > 2. All '1' should be changed to '2', but only if the same
 >    position on the next line is '1'.
 > 3. All '13' should be changes to '99', but only if the same
 >    positions on the next line is ' 1'.

Try the following awk script:

Quote:>>>>>>>>>>>>>>>>>>>>>(CUT)<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

nawk '
    {
        if ( $0 ~ /XX$/ ) {
            First = $0
            len = length (First)
            getline
            for ( i=1; i<=len; i++ ) {
                # No. 3: change "13" to "99"
                if ( i > 2 && substr (First, i, 2) == "13" &&
                        substr ($0, i, 2) == "11" ) {
                    First = substr (First, 1, i-1) "99" substr (First, i+2)
                }
                # No. 2: change "1" to "2"
                if ( substr (First, i, 1) == "1" &&
                        substr ($0, i, 1) == "1" ) {
                    First = substr (First, 1, i-1) "2" substr (First, i+1)
                }
            }
            print First
            print
        } else {
            print
        }
    }
' FILE

Quote:>>>>>>>>>>>>>>>>>>>>>(CUT)<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

Heiner
--
     -------------------------------------------------------------

   / BinTec Communications      / mine, not BinTec's --       /
  / Willstaetter Str. 30 ------- ...even if they should be ;-)/

------------------------------------------------------------
 
 
 

Shell problem: How to change text in a line depending on data in the following line.

Post by Scott Erw » Wed, 22 May 1996 04:00:00



>Hi,
>Basicly a simple problem, but more complex in UNIX-Shell programming.
>1. Changes is to be done only to lines ending with XX.
>2. All '1' should be changed to '2', but only if the same position on
>the next line is '1'.
>3. All '13' should be changes to '99', but only if the same positions
>on the next line is ' 1'.
>I have to solve the problem using standard UNIX, so perl is not an
>option.

Well, this was a good chance to brush up on my awk programming.  I
have a solution that I think works in most cases.  I never found a
case it didn't work.  Here is MY solution; I'm sure there are many.

BEGIN { bUseLine=0 }

#-------------------------------------
# createMask
#-------------------------------------
function createMask(prev, curr) {
   msk=""
   is13=0
   for (i=1; i<=length(prev); i++) {
      if (substr(prev,i,2) == "13")
         if (substr(curr,i,2) == "11") {
            is13=1
            msk=msk "9"
         } else if (substr(curr,i,1) == "1")
            msk=msk "2"
         else
            msk=msk " "
      else if (substr(prev,i,1) == "1")
         if (substr(curr,i,1) == "1")
            msk=msk "2"
         else
            msk=msk " "
      else if (substr(prev,i,1) == "3" && is13) {
         msk=msk "9"
         is13=0
      } else
         msk=msk " "
   }

   return msk

Quote:}

#-------------------------------------
# applyMask
#-------------------------------------
function applyMask(prev, msk) {
   outStr=""

   for(i=1; i<=length(prev); i++) {
      mskChar = substr(msk,i,1)
      if (mskChar == " ")
         outStr = outStr substr(prev,i,1)
      else
         outStr = outStr mskChar
   }
   return outStr

Quote:}

#-------------------------------------
# Main body
#-------------------------------------
{
   if (bUseLine) {
      bUseLine=0
      mask = createMask(prevLine, $0)
      print applyMask(prevLine, mask)
   } else
      print prevLine

   if ($0 ~ /XX$/)
      bUseLine=1

   prevLine = $0

Quote:}

END {print prevLine}

--
Scott Erwin                

"It never hurts to help!" -Eek the Cat

 
 
 

Shell problem: How to change text in a line depending on data in the following line.

Post by Bill Zissimopoulo » Wed, 22 May 1996 04:00:00



> Hi,

> Basicly a simple problem, but more complex in UNIX-Shell programming.

> File:
> 122331133XX
> 11   11  11
> 22244422233323
> werrwr
> weer4213131e2XX
> 11  1     11  1
> 2341123XX
> 11  1
> 2422
> 424211
> 24dwq4
> End of file

> I have to change text in a file like the one above.

> 1. Changes is to be done only to lines ending with XX.
> 2. All '1' should be changed to '2', but only if the same position on
> the next line is '1'.
> 3. All '13' should be changes to '99', but only if the same positions
> on the next line is ' 1'.

> I have to solve the problem using standard UNIX, so perl is not an
> option.

I think it is possible using sed and the hold buffer. However, in this
case I would certainly use awk. Awk is a programming language and as
such makes tasks like that easy.

Now don't ask me to write you the script (unless you want to send me
your salary :-)

Bill
--

<http://www-dept.cs.ucl.ac.uk/students/B.Zissimopoulos/>

 
 
 

Shell problem: How to change text in a line depending on data in the following line.

Post by Scott Erw » Thu, 23 May 1996 04:00:00




> > Basicly a simple problem, but more complex in UNIX-Shell
> > programming.

-snip-

Quote:>>>>>>>>>>>>>>>>>>>>>>(CUT)<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
>nawk '
>    {
>    if ( $0 ~ /XX$/ ) {
>        First = $0
>        len = length (First)
>        getline
>        for ( i=1; i<=len; i++ ) {
>            # No. 3: change "13" to "99"
>            if ( i > 2 && substr (First, i, 2) == "13" &&

By putting in the requirement that i be > 2, you can't handle the case
where a 13 is at the beginning of a line.  If you take it out, it will
work.  It makes the substr (First, 1, i-1) below return *nothing*, but
that's what you want in that case.

Quote:>                    substr ($0, i, 2) == "11" ) {
>                First = substr (First, 1, i-1) "99" substr (First, i+2)
>            }
>            # No. 2: change "1" to "2"
>            if ( substr (First, i, 1) == "1" &&
>                    substr ($0, i, 1) == "1" ) {
>                First = substr (First, 1, i-1) "2" substr (First, i+1)
>            }
>        }
>        print First
>        print
>    } else {
>        print
>    }
>    }
>' FILE
>>>>>>>>>>>>>>>>>>>>>>(CUT)<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

-snip-

Excellent solution.  I timed it against mine and it was faster (less
code to process).

--
Scott Erwin                

"It never hurts to help!" -Eek the Cat

 
 
 

1. How to display the line with a string AND the following line of text?

All -

I am using the hplog utility under Red Hat Entperprise Linux 3 to
watch for hardware problems on a bunch of ProLiant servers.

It spits out log info that looks like this:

ID   Severity       Initial Time      Update Time       Count
-------------------------------------------------------------
0000 Information    12:37  07/21/2004 12:37  07/21/2004 0001
LOG: IML Cleared (Message Log Cleared by userfoo)

0001 Critical       12:59  07/21/2004 12:59  07/21/2004 0001
LOG: Disk failure on device blah

I don't care about "Information" messages like the first one, only
Critical or Caution messages.  I am wondering if there is a way via
sed, grep or awk to grab any line that contains Critical or Caution
plus the line afterwards?

So I would only get:

0001 Critical       12:59  07/21/2004 12:59  07/21/2004 0001
LOG: Disk failure on device blah

Thanks!
Thomas

2. exabyte 8505C on Linux

3. How to read text line-by-line in shell script?

4. Permissionsproblem with DHCP and NIS+ at Solaris 2.6

5. Sed: merging lines recursively depending on line pattern

6. umount reports partition in use

7. Ensuring a line follows another line

8. Signal handling esp on LINUX

9. How can awk can read the following lines of a line searched?

10. Insert a line of text every nth line

11. e-mail subject line and text in single command line

12. adding new line to external text file below a line that contains <string>

13. irc problem on shell acct. just see 1 line of text