0

I want to delete specific two consecutive lines matching patterns from specific line from a file.

For e.g. file contents are like below.

Line1: a
Line2: b
Line3: c
Line4: Name: 123
Line5:  xyz
Line6: Name: 456
Line7:  abc

I want to find the lines starting from line 4, matching 1st line pattern starting with "Name: " and matching 2nd line pattern starting with whitespace and delete the two consecutive lines.

Any efficient way to do this in shell using sed or something else?

To be a bit more clear, I want to remove signing/checksum information from the MANIFEST.MF.

Sample MANIFEST.MF like below: From the below manifest file, I want to remove the entry "Name: ". where "Name: " entry can be in one line or 2(or more) lines.

Initially my solution was like find the first "Name: " entry followed by "SHA-256-Digest: " entry and delete to the end of the file. Unfortunately this solution has a problem of removing one needed entry in the middle. For e.g. "NetBeans-Simply-Convertible: " is also being removed.

So, now I want to remove "Name: " entry if available in 1 line or entry spanned across 2 or more lines. But I should not lose entries like "NetBeans-Simply-Convertible: " while removing "Name: " entries.

Already I am removing "SHA-256-Digest: " entries with the below command on file with sed -i "/^\SHA-256-Digest: /d" $manifest_file


Manifest-Version: 1.0
Version-Info: ....

Name: com/abc/xyz/pqr/client/relationship/message/notifier/Relati
 onshipUpdateNotifierFactory.class
SHA-256-Digest: cSSyk6Y2L2F9N6FPtswUkxjF2kelMkGe4bFprcQ+3uY=

Name: com/abc/xyz/pqr/client/relationship/ui/BaseRelationshipView
 $5.class
SHA-256-Digest: w9HgRjDuP024U4CyxeKPYFe6rzuzxZF3b+9LVG36XP8=

Name: com/abc/xyz/pqr/client/impl/MofRelationshipAgentImpl.class
SHA-256-Digest: GwIBIU+UdPtjyRhayAVM90Eo+SwCT/kP65dI59adEnM=

Name: com/abc/xyz/pqr/client/settings/ConvertibleProperties.class
NetBeans-Simply-Convertible: {com/abc/xyz/pqr/client/settings}Con
 vertibleProperties
SHA-256-Digest: 5FszAtfpPXcLx/6FBWbfeg6E4fwFMRozV+Q+3rReATc= ...

Expected Output:

Manifest-Version: 1.0
Version-Info: ....


NetBeans-Simply-Convertible: {com/abc/xyz/pqr/client/settings}Con
 vertibleProperties

...
3
  • So you want to delete a line that matches a pattern and the next line after it? Commented Apr 15, 2017 at 6:23
  • what is the expected output... will line 6 and 7 be deleted as well? and add sample input where it doesn't match and should not be deleted
    – Sundeep
    Commented Apr 15, 2017 at 6:26
  • Hi Stephen,Sundeep, I elaborated a bit more about the problem. Please check. Thanks. Commented Apr 16, 2017 at 4:12

4 Answers 4

0

awk approach:

Let's say we have the following input file file.txt(considering that each line contains Line<number>: as first field):

Line1: a
Line2: b
Line3: c
Line4: Name: 123
Line5:  xyz
Line6: Name: 456
Line7:  abc
Line8: Name: 111
Line9: www
Line10: Num: 222
Line11:  abc
Line12: Name: 333
Line13:  ccc

awk '{ if ($2 == "Name:") { 
           if ((getline l) > 0){ 
               if (l ~ /^\S+  \S+/) { next } else { print $0 RS l }               
           }
       } else { print } 
}' file.txt

The output:

Line1: a
Line2: b
Line3: c
Line8: Name: 111
Line9: www
Line10: Num: 222
Line11:  abc

‘getline var’ - reads the next record from awk's input into the variable var

The getline command returns 1 if it finds a record and 0 if it encounters the end of the file.

1
  • Hi Roman, I elaborated the problem bit more. Please check once. Thanks. Commented Apr 16, 2017 at 4:14
0

You see that what you are asking is not clear: one answer deletes 4 lines (the two matching and the two subsequent ones); another deletes everything but the matching lines...

I'll throw in what I understand you want: I delete 2 lines, the one matching Name: 123 and the subsequent one. I do this with sed:

sed -e '/Name: 123/{N;d}' filename
1
  • Hi Dario, I elaborated the problem bit more. Please check once. Thanks Commented Apr 16, 2017 at 4:13
0

Using ed:

$ printf '%s\n' 'g/^ / s///\' '-,.j' 'g/^Name: /d' 'g/SHA-256-Digest: /d' '4,$g/^$/d' ,p Q | ed -s file
Manifest-Version: 1.0
Version-Info: ....

NetBeans-Simply-Convertible: {com/abc/xyz/pqr/client/settings}ConvertibleProperties

This applies the following edit script to you input file:

g/^ / s///\
-,.j
g/^Name: /d
g/SHA-256-Digest: /d
4,$g/^$/d
,p
Q

This consists of six separate commands:

  1. The two commands s/// and -,. j applied to every line that starts with a space character. The empty regular expression in the s command re-uses the expression ^ from the preceding g command (which is used for applying one or more commands to lines matching a regular expression), so the s command removes the first empty space on lines that start with empty spaces. The j command then joins the modified line with the previous line. This effectively undoes the wrapping of the lines in the input data.

  2. The command d is applied to all lines that start with Name: , removing these.

  3. Similarly, lines starting with SHA-256-Digest: are removed.

  4. Empty lines are removed from line 4 onwards.

  5. We output the complete buffer to standard output to display the result.

  6. Q quits the editor unconditionally (you could use wq to write the changes back to the original file).

-1
sed -e '
   4,$!d;      # skip non-relevant portion
   /Name:/N;   # grab the line coming after Name:
   /\n.* /d;   # what we were after is not this
   P;D
' yourfile
3
  • Hi Rakesh, I elaborated the problem bit more. Please check once. Thanks. Commented Apr 16, 2017 at 4:14
  • HI Rakesh, 4, $!d is deleting the lines from 1 line to 4th line. What I want is, I want to keep the 1st three lines untouched, means I don't want to delete. I wan sed command to act from 4th line. Thanks Commented Apr 16, 2017 at 4:51
  • This appears to produce garbage I afraid.
    – Kusalananda
    Commented Sep 19, 2023 at 14:15

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .