I have a a requirement to grep patterns from a file but need them in order.
$ cat patt.grep
name1
name2
$ grep -f patt.grep myfile.log
name2:some xxxxxxxxxx
name1:some xxxxxxxxxx
I am getting the output as name2 was found first it was printed then name1 is found it is also printed. But my requirement is to get the name1 first as per the order of patt.grep file.
I am expecting the output as
name1:some xxxxxxxxxx
name2:some xxxxxxxxxx
i tried the same situation and easily solved using below command:
I think if your data in the same format as you represent then you can use this.
This can't be done in
grep
alone.For a simple and pragmatic, but inefficient solution, see owlman's answer. It invokes
grep
once for each pattern inpatt.grep
.If that's not an option, consider the following approach:
grep
in a single pass,patt.grep
usingawk
:-
, i.e., through the pipe) into an assoc. array using the 1st:
-based field as the keypatt.grep
and prints the corresponding output line, if any.Constraints:
patt.grep
match the 1st:
-based token in the log file, as implied by the sample output data in the question.awk
solution would have to be made more sophisticated.Use the regexes in
patt.grep
one after another in order of appearance by reading line-wise:A simple workaround would be to
sort
the log file beforegrep
:However, this might not yield results in the desired order if
patt.grep
is not sorted.In order to preserve the order specified in the pattern file, you might use
awk
instead:This should do it
awk -F":" 'NR==FNR{a[$1]=$0;next}{ if ($1 in a) {print a[$0]} else {print $1, $1} }' myfile.log patt.grep > z
You can pipe
patt.grep
toxargs
, which will pass the patterns togrep
one at a time.By default
xargs
appends arguments at the end of the command. But in this case,grep
needsmyfile.log
to be the last argument. So use the-I{}
option to tellxargs
to replace{}
with the arguments.