How to delete the previous line after pattern match?

Team,

I am writing a shell script to perform few health checks of the system, where I need to delete the previous line in the text file after pattern match using sed (or) awk.

Could you please help me out on this?

For example,

<td>
<td style=color:green align=center>
</td>
</tr>
</table>

I want the pattern to be matched as "<td style=" but only the previous line "<td>" to be removed. So, the output should look like follows:

<td style=color:green align=center>
</td>
</tr>
</table>

This is on AIX.

Hello Nagaraj R,

Welcome to forums, please use code tags for commands/codes/Inputs which you are using into your posts as per forum rules. Could you please try following and let me know if this helps you.

awk '{if($0 ~ /<td style/){Q=$0;} else {if(Q){print Q}};Q=$0}'   Input_file

If you may have any empty lines into your Input_file then following may help you in same.

awk '{if($0 ~ /<td style/){Q=$0;} else {if(NR>1){print Q}};Q=$0}'  Input_file

Output will be as follows.

<td style=color:green align=center>
</td>
</tr>

Thanks,
R. Singh

1 Like

Try also

sed '/<td>/ {N;s/^<td>\n\(<td style=\)/\1/}' file
1 Like

A Unix sed needs a newline or a semicolon before the closing }

sed '/<td>/ {$!N;s/^<td>\n\(<td style=\)/\1/;}' file

Also most Unix sed have the bug to not do the default print if there is a N command on the last input line, therefore the usual workaround.

1 Like

MadeInGermany's answer in sed is worthy of study.

 If we found <td> first check to see if this is not the last line "$!", append
 the next line "N" into the pattern space which now contains two lines separated
 by newline "\n".  The \(through\) identifies a pattern (here the word "through")
 to be played back with \1.  The "s" command finds <td> on one line and
 <td style= on the next and replaces it with just <td style=, deleting the first line
 and keeping the next one intact.
1 Like

Thank you Rudic and MadeInGermany. It worked and helped me to get this task done.

Thank you others as well for the response.!!

Hi.

The command ed may be easier for some folks to understand:

#!/usr/bin/env bash

# @(#) s1       Demonstrate find match, delete previous line, ed.

# Utility functions: print-as-echo, print-line-with-visual-space, debug.
# export PATH="/usr/local/bin:/usr/bin:/bin"
LC_ALL=C ; LANG=C ; export LC_ALL LANG
pe() { for _i;do printf "%s" "$_i";done; printf "\n"; }
pl() { pe;pe "-----" ;pe "$*"; }
em() { pe "$*" >&2 ; }
db() { ( printf " db, ";for _i;do printf "%s" "$_i";done;printf "\n" ) >&2 ; }
db() { : ; }
C=$HOME/bin/context && [ -f $C ] && $C ed pass-fail

original=${1-original}
FILE=data1
rm -f $FILE
cp $original $FILE
E=expected-output.txt

pl " Input data file $FILE:"
cat $FILE

pl " Expected output:"
cat $E

# Find match, current line number is in symbol "."
# The previous line is ".-1", so delete that line.
pl " Results, from ed:"
ed $FILE <<EOF
/<td style=/
.-1d
w
q
EOF

pl " Results, content of edited file:"
tee f1 < $FILE 

pl " Verify results if possible:"
C=$HOME/bin/pass-fail
[ -f $C ] && $C || ( pe; pe " Results cannot be verified." ) >&2

exit 0

producing:

$ ./s1

Environment: LC_ALL = C, LANG = C
(Versions displayed with local utility "version")
aix 7.1.0.0
bash GNU bash 4.2.10
ed - ( /usr/bin/ed, Sep 5 2012 )
pass-fail - ( local: RepRev 1.8, ~/bin/pass-fail, Nov 18 17:57 )

-----
 Input data file data1:
<td>
<td style=color:green align=center>
</td>
</tr>
</table>

-----
 Expected output:
<td style=color:green align=center>
</td>
</tr>
</table>

-----
 Results, from ed:
62
<td style=color:green align=center>
57

-----
 Results, content of edited file:
<td style=color:green align=center>
</td>
</tr>
</table>

-----
 Verify results if possible:

-----
 Comparison of        4 created lines with        4 lines of desired results:
 Succeeded -- files (computed) f1 and (standard) expected-output.txt have same content.

Best wishes ... cheers, drl