Join two commands sed and grep

Hi all,

I have two separate commands which I would like to join. Basically, I want to match a line and insert a character at the end of the previous line to the matched line

Here is what I have got

grep -B1 '^>'
sed 's/$/*/'

Any help is much appreciated thanks

if i understand your requirement correctly, you want to search for a line with matching pattern and append something. you can try this

im just appending string 'matched' to the end of the line.

[oracle@server ~]$ cat infile
1
2
3
4
5
[oracle@server ~]$ sed 's/5.*/&matched/g' infile
1
2
3
4
5matched
[oracle@server ~]$ sed 's/2.*/&matched/g' infile
1
2matched
3
4
5
$ cat f
line one
line to match PATTERN
last line
$ awk 'b{if($0~/PATTERN/)b=b"@@";print b}{b=$0}END{print b}' f
line one@@
line to match PATTERN
last line

Hi riyandgreat 25 and ripat,

Riyandgreat 25 - I want to append a character to the line before the matched line and not the matched line. Thanks so much

Ripat - your solution worked great. Thanks

Note that ripat's awk script will delete all empty lines and all lines that consist entirely of a string of "0" characters.

The following ed script doesn't ignore empty lines and doesn't ignore lines that only contain a string of "0"s. Note that the patterns accepted by awk (which uses extended regular expressions) and ed (which uses basic regular expressions) are slightly different. If that difference doesn't matter to you, you can try this simple ed script:

#!/bin/ksh
FILE=${1:-f}
PATTERN=${2:-PATTERN}
REPLACE=${3:-@@}
ed -s "$FILE" <<-EOF
	2,\$g/$PATTERN/.-1s/$/$REPLACE/
	1,\$p
	Q
EOF

With the file f containing a few more lines than were in ripat's example:

PATTERN on line1
line two
line to match PATTERN
last line

PATTERN after empty line
000
PATTERN after 000
0
PATTERN after 0
 
PATTERN after blank line

where the next to the last line just contains a space character, the ed script above produces the output:

PATTERN on line1
line two@@
line to match PATTERN
last line
@@
PATTERN after empty line
000@@
PATTERN after 000
0@@
PATTERN after 0
 @@
PATTERN after blank line

while ripat's awk script produces the output:

PATTERN on line1
line two@@
line to match PATTERN
last line
PATTERN after empty line
PATTERN after 000
PATTERN after 0
 @@
PATTERN after blank line

If your pattern or the string to be added to lines before those matching the pattern contain any slash ( / ) characters, replace the slashes in the ed g and s commands with a character (other than a newline character) that will never appear in your pattern or added text. I frequently use a control-G for this when processing files that don't contain any ASCII BEL (sometimes called alert) characters (it shows up nicely when I'm editing the script with vi, but it is sometimes hard to describe in text to naive users).

If the difference between BREs and EREs matters, the following awk script will produce the same output as the ed script above. With any of these scripts, if the regular expression contains any meta-characters used in the type of RE you're using, they will have to be escaped appropriately. If you're using ed, you also have to consider what can happen with ampersand ( & ) and backslash digit ( \x 1 <= x <= 9) in the replacement string. With both ed and awk, special attention will also be required if the pattern and replacement strings contain any dollar signs ( $ ).

#!/bin/ksh
FILE=${1:-f}
PATTERN=${2:-PATTERN}
REPLACE=${3:-@@}
awk -v pat="$PATTERN" -v rep="$REPLACE" '
FNR>1 { if($0 ~ pat)    print last rep
        else            print last
}
{       last = $0 }
END {   print last }' "$FILE"

As always when writing new awk scripts, if you are using a Solaris/SunOS system, use /usr/xpg4/bin/awk , /usr/xpg6/bin/awk , or nawk instead of /bin/awk or /usr/bin/awk .

Note that although I used the Korn shell to test these scripts, any POSIX conforming shell will work. If you don't need the script to provide default values for the file to be processed, the pattern to use, and the string to be added to the lines prior to the lines containing the pattern, you can easily hard wire those values into either of the above scripts and use any shell you want.

Hope this helps...

1 Like

True. Just adapted my snippet.

$ awk 'NR>1{if($0~/PATTERN/)b=b"@@";print b}{b=$0}END{print b}' f