0

I have a log file, which contains the following data:

2019-02-11 00:05:58.241 [exec-178] Start request
2019-02-11 00:05:58.242 [exec-178] customer_name
2019-02-11 00:05:58.243 [exec-178] other process
2019-02-11 00:05:58.244 [exec-178] other process
2019-02-11 00:05:58.245 [exec-178] results
2019-02-11 00:05:58.246 [exec-178] End request (13ms)

I want to use a single grep command to capture 'customer_name' and 'End request'. I have been trying to use grep -E "[0-9]{2,4}ms but it does not provide the expected output.

Expected output:

2019-02-11 00:05:58.242 [exec-178] customer_name 
2019-02-11 00:05:58.246 [exec-178] End request (13ms)
  • I have edited your question a bit to improve the formatting. But your requirement is still somewhat vague. Do you just want to search for the fixed strings 'customer_name' and 'End request'? – Haxiel Feb 14 at 10:36
  • Yes and correct – julian lee Feb 14 at 10:38
  • @julianlee What is the expected output? – Nasir Riley Feb 14 at 10:39
  • Is this grep enough for your job? grep -E 'customer_name|End request' ? It will match line containing customer name or End Request in any position of the line. – George Vasiliou Feb 14 at 10:40
  • @NasirRiley 2019-02-11 00:05:58.242 [exec-178] customer_name 2019-02-11 00:05:58.246 [exec-178] End request (13ms) – julian lee Feb 14 at 11:47
0

It's possible with grep -E and the patterns that you grep for are sepearted by a pipe sign.

[root@server ~]# grep -Ei "customer_name|end request" file 
2019-02-11 00:05:58.242 [exec-178] customer_name
2019-02-11 00:05:58.246 [exec-178] End request (13ms)
[root@server ~]# 

Extracted from man grep:

-E, --extended-regexp Interpret PATTERN as an extended regular expression (ERE, see below).

-i, --ignore-case Ignore case distinctions in both the PATTERN and the input files.

0

Searching for fixed strings with grep is really straightforward. You can pass multiple patterns to grep using the -e option:

$ cat testfile
2019-02-11 00:05:58.241 [exec-178] Start request
2019-02-11 00:05:58.242 [exec-178] customer_name
2019-02-11 00:05:58.243 [exec-178] other process
2019-02-11 00:05:58.244 [exec-178] other process
2019-02-11 00:05:58.245 [exec-178] results
2019-02-11 00:05:58.246 [exec-178] End request (13ms)

$ grep -F -e 'customer_name' -e 'End request' testfile
2019-02-11 00:05:58.242 [exec-178] customer_name
2019-02-11 00:05:58.246 [exec-178] End request (13ms)

The -F option is used to specify that you are searching for fixed strings. It is not quite necessary, but it helps to make the command more explicit.

You could also simply the command a bit using an extended regular expression. The expression A|B is used to search for 'A' or 'B'.

$ grep -E 'customer_name|End request' testfile
2019-02-11 00:05:58.242 [exec-178] customer_name
2019-02-11 00:05:58.246 [exec-178] End request (13ms)
  • Thanks you for giving me the idea. It work perfectly with the command you provide me. I can get the necessary info by enhance the command. grep -FA 5 "customer_name" | grep -B 5 "End request" – julian lee Feb 14 at 11:08
  • @julianlee That's great. If my answer has resolved your problem, you could accept it by clicking on the tick mark next to it. You should also look at the other answers posted here before making a choice. Accepting an answer grants reputation to both parties - the asker and the answerer. – Haxiel Feb 14 at 11:25
  • Sorry i am new here, where is the tick mark next to it? – julian lee Feb 14 at 11:49
0

If you just want it to return those exact strings which are on separate lines:

egrep -o "customer_name|End request" logfile

Output:

customer_name
End request

If you want it to return the entire lines:

egrep "customer_name|End request" logfile

Output

2019-02-11 00:05:58.242 [exec-178] customer_name
2019-02-11 00:05:58.246 [exec-178] End request (13ms)
0

To get everything between and including your search lines, use awk:

awk 'BEGIN {found=0}; /customer_name/ {found=1}; found {print}; /End request/ {found=0}' logfile

And if your "customer_name" is not a static string, but different values, try using -v, eg.:

awk -v "name=sally" 'BEGIN {found=0}; index($0, name) {found=1}; found {print}; /End request/ {found=0}' logfile

or with nicer formatting and explanation but harder to copy and paste:

awk -v "name=sally" 'BEGIN {
        # good style, but optional... nonexistent variables are already 0
        found=0;
    };
    index($0, name) {
        # remember that we found the first line
        found=1;
    }; 
    found {
        # since we print after the found=1, we print that line
        # and also the lines between
        # and since we set found=0 after already printing the end line, we are printing that too
        print;
    }; 
    /End request/ {
        # mark that we stop printing
        found=0;
    };' logfile
  • He only wants to print the two lines with the text that he specified. This prints absolutely everything and is effectively no different than using cat. – Nasir Riley Feb 14 at 13:09
  • @NasirRiley the OP added a comment to Hexiel's answer saying that -A5 made it do what he wanted, which means he didn't only want those 2 lines. And you only get "absolutely everything" if your file is only his example output, and nothing in between multiple instances of those 2 lines. – Peter Feb 14 at 20:09
  • That wasn't stated anywhere in his question. In fact, in his comments to the question, he clearly stated that he just wanted those two lines and gave the expected output as those two lines. Secondly, it's entirely possible that a log file could contain only those lines depending on what was being written to it and for how long. I'm only suggesting that what he stated he wanted is totally different than what he would get from Hexial's answer which he stated worked perfectly and that there should be more clarity. – Nasir Riley Feb 14 at 22:41

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.