5

How can I match a pattern, delete the pattern and also the next and the previous line on Solaris 10? I'm hiting the wall because Solaris does not come with GNU sed. Given the following file content:

    LinearFile(3F007F106F3B, FDN, 29, 20)
    LinearFile(3F007F106F40, XXX, 29, 1)
    {
        LinearRec(1, 12345)
    }
    LinearFile(3F007F106F3C, SMS, 176, 20)
    LinearFile(3F007F106F4F, ECCP, 15, 10)
    LinearFile(3F007F106F40, XXX, 29, 1)
    {
      LinearRec(1, FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)
    }
    LinearFile(3F007F106F42, SMSP, 43, 3)
    BinaryFile(3F007F106F43, SMSS, 2)
    LinearRec(1, 12345)

I would like to remove the block that contain:

    {
      LinearRec(1, FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)
    }

The file would be:

LinearFile(3F007F106F3B, FDN, 29, 20)
    LinearFile(3F007F106F40, XXX, 29, 1)
    {
        LinearRec(1, 12345)
    }
    LinearFile(3F007F106F3C, SMS, 176, 20)
    LinearFile(3F007F106F4F, ECCP, 15, 10)
    LinearFile(3F007F106F40, XXX, 29, 1)
    LinearFile(3F007F106F42, SMSP, 43, 3)
    BinaryFile(3F007F106F43, SMSS, 2)
    LinearRec(1, 12345)

To delete the next line I issued the following:

sed -e '/LinearRec(1\,\ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)/{n;d;}' file.txt

What about the line that matchs and the previous line?

Maybe it can be achieved by using ed or vi? Thx!

  • The only restriction is not to use sed? grep and awk are fine? – Kira Nov 4 '15 at 15:04
  • No, you can use any tool. There's no restriction. – Jonathan Nov 4 '15 at 16:21
3

A perl approach (assuming your file is small enough to load into memory):

perl -0pe 's/.+?\n.*?LinearRec\(1, F{58}\).*?\n.*?\n//' file

The -0 makes perl slurp the entire file, and the -p tells it to print each input line after applying the script given by -e. The script itself matches 58 Fs and the surrounding two lines and removes them.

  • I changed a little to direct change the file. perl -0pi -e... – Jonathan Nov 4 '15 at 16:39
  • There's any way to change F{58} to F like @mikeserv suggestion? – Jonathan Nov 4 '15 at 16:45
  • 1
    @Jonathan sure, you can use the same format as Mike did: perl -0pe 's/.+?\n.*?LinearRec\(1, *FF*\).*?\n.*?\n//' file – terdon Nov 4 '15 at 16:48
5

Here's an ed script:

ed <<\!
e file.txt
/LinearRec(1, FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)
-1,+1d
w newfile.txt
!

It writes the output to file newfile.txt.


The "global" repeated version of this is

ed <<\!
e file.txt
g/LinearRec(1, FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)/-1,+1d
w newfile.txt
!
  • 1
    you should do those more often. i like ed. – mikeserv Nov 4 '15 at 15:44
  • After some time I managed to do with VI, but the problem is that if the delete does not work, vi will not quit the file. vi -c ':g/LinearRec(1, FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)/-1,+1 d|:x' file.txt This also happens using ed? – Jonathan Nov 4 '15 at 16:23
  • I don't see anything wrong with what you are doing. It works for me, but I'm not on solaris. I looked at the online man pages for ed and they seem to match what I am using. – meuh Nov 4 '15 at 16:42
  • Sorry to not be more specific. If I run the vi -c on a file that there's no LineaRec(...), vi will open the file, go to the last line and will not quit. The save and quit, ":x" will not run. – Jonathan Nov 4 '15 at 20:43
  • 1
    Try separating the commands into 2 -c options: vi -c ':g/..../-1,+1d' -c ':x' file.txt. – meuh Nov 4 '15 at 21:11
3
sed -ne'$p;N;/^ *{ *\n *LinearRec(1, *FF*) *$/n;/\n/P;D' <in >out

That gets sed a one-line look-ahead, and then only Prints to output any lines which don't fit your series, because it jumps one more and dumps the buffer when it matches the first two lines of it.

  • sed on solaris does not have -i, there's any way to change the file directly without it? – Jonathan Nov 4 '15 at 16:42
  • 2
    @Jonathan - neither perl's -i nor GNU sed's -i have ever directly modified a file, and are actually writing your edits to a temporary file that they then mv over the target file at end of input. You could easily do the same with sed ... <in >out && mv out in or in Solaris 10's /bin/sh (which ought to be Bourne) sed ... <<IN >infile\n`cat <infile`\nIN\n where the \n stand here in the comment for actual newlines. – mikeserv Nov 4 '15 at 16:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.