Is is possible to find first string occurrence from the end of file using awk
or sed
? Or I will need to use some scripting language like Python or Perl?
Asked
Active
Viewed 1,834 times
3

Benjamin W.
- 46,058
- 19
- 106
- 116

JackTheKnife
- 3,795
- 8
- 57
- 117
-
Please post sample Input_file and expected output in code tags into your post. – RavinderSingh13 Jan 18 '18 at 16:10
-
@RavinderSingh13 Any email message in EML format which was forwarded multiple times. I want to extract original message. It came up that first `Return-Path:` from the bottom of EML file indicates that original message. – JackTheKnife Jan 18 '18 at 16:13
-
If you could give a sample example(you could hide actual things off course) it will be good for us to understand requirements please. – RavinderSingh13 Jan 18 '18 at 16:25
-
Forgive me, I found it easier to answer than to search for the duplicate. :) But yeah, this is definitely a duplicate. – hek2mgl Jan 18 '18 at 16:46
3 Answers
6
You can revert the order of lines in the file with tac
(the opposite of cat
) and then use grep
:
tac file | grep -m 1 STRING
grep -m1
gives you only the first occurrence.
Alternatively you may just pipe grep
to tail
:
grep STRING | tail -n1
If you want to use awk
:
awk 'BEGIN{res=""}/STRING/{res=$0}END{if(res!=""){print res}}' file
Explanation:
# Initialize result with an empty string
BEGIN{res=""}
# If STRING is found, store the current line in res.
# This will overwrite a previous result, giving you
# always only the last occurrence.
/STRING/{res=$0}
# Once the end of input has been reached print the result
# if STRING was found.
END{if(res!=""){print res}}

hek2mgl
- 152,036
- 28
- 249
- 266
-
1
-
-
I have ended up with that code `tac $file | sed -n '1,/^Return-Path:/p;' | sed -ne "/^--$wrapping_boundary/d;p" | tac > out/$file` – JackTheKnife Jan 18 '18 at 17:29
4
Using sed
sed -n '/string/h;${x;p}' infile
Using awk
tac infile | awk '/abc/{print;exit}'
Test Results:
akshay@db-3325:/tmp$ cat infile
abc 1
xyz 2
pwd 3
cwd 4
aks 5
axy 6
abc 7
xyz 8
nwd 9
akshay@db-3325:/tmp$ sed -n '/abc/h;${x;p}' infile
abc 7
akshay@db-3325:/tmp$ tac infile | awk '/abc/{print;exit}'
abc 7

Akshay Hegde
- 16,536
- 2
- 22
- 36
-
Just in my defense, I haven't copied the `awk` solution from here please, seems to be our timings were almost same :) – RavinderSingh13 Jan 18 '18 at 16:54
3
Following tac
and awk
combination will help you to read the very first occurrence of any string very quickly.
tac Input_file | awk '/STRING/{print;exit}'
Explanation: tac
will reverse the Input_file then awk
will check for the string and as soon as it gets it will print the line and exit from it, since are only bothered about very first occurrence so no need to read whole Input_file here.

RavinderSingh13
- 130,504
- 14
- 57
- 93