Home > Back-end >  Combine two grep commands to process input from a file or grep lines starting with one specific subs
Combine two grep commands to process input from a file or grep lines starting with one specific subs

Time:11-18

I have a file that i want to pars using grep command, the file consist of lines like this:

NVO,0,267,61,247357,247357,O,19:00:00.000000,06:09:08.417320,07:55:22.068670
DVD,0,267,61,247357,247357,O,19:00:00.000000,06:09:08.417320,07:55:22.068670
NVO,0,267,61,247358,247358,B,19:00:00.000000,06:09:08.417407,07:55:22.079291
DVD,0,267,61,247358,247358,B,19:00:00.000000,06:09:08.417407,07:55:22.079291

I want to get only the line that start with NVO, and have ,B, in the line. the out put should look like this:

NVO,0,267,61,247358,247358,B,19:00:00.000000,06:09:08.417407,07:55:22.079291

to get the NVO, line I'm using grep ^NVO, file_name.txt but I'm unable to add the second condition ,B, I tried grep '^NVO,|,B,' file_name.txt and also

grep ",B," | grep "^NVO," file_name.txt 

with no luck I know I can do it with two commands, the first to write to file and then to do a second grep command with the ,B, filter

CodePudding user response:

The operation you're attempting does not actually require combining two grep calls. Therefore, you can use

grep "^NVO,.*,B," file > outfile

Details:

  • ^ - string start
  • NVO, - an NVO, string
  • .* - any text (any zero or more chars)
  • ,B, - a ,B, text.

See the online demo:

#!/bin/bash
s='NVO,0,267,61,247357,247357,O,19:00:00.000000,06:09:08.417320,07:55:22.068670
DVD,0,267,61,247357,247357,O,19:00:00.000000,06:09:08.417320,07:55:22.068670
NVO,0,267,61,247358,247358,B,19:00:00.000000,06:09:08.417407,07:55:22.079291
DVD,0,267,61,247358,247358,B,19:00:00.000000,06:09:08.417407,07:55:22.079291'
grep "^NVO,.*,B," <<< "$s"

Output:

NVO,0,267,61,247358,247358,B,19:00:00.000000,06:09:08.417407,07:55:22.079291

CodePudding user response:

Adding this for folks who actually have a good reason to combine two separate grep calls -- the answer by Wiktor is appropriate in your case, where you don't.


The problem here is that your last copy of grep is completely ignoring the input from the first one, because you're passing it a filename to read -- so it reads the file and ignores the prior instance. (Also, you aren't telling the first grep where to get input from, so it's reading from stdin).

You can fix that by passing the filename to the first component of the pipeline:

grep ",B," input_file | grep "^NVO," >output_file

...or passing the input file as stdin:

<input_file grep ',B,' | grep '^NVO,' >output_file

Alternately, if you want to treat both greps as a unit, and pass their stdin and stdout at the end, you can do that:

{ grep ',B,' | grep '^NVO,'; } <input_file >output_file
  • Related