I am attempting to return the first occurrence of multiple strings, ie, I want to select the lines from the following text where the first occurrence of 1259, 3009, and 1589 happen.
ADWN 1259 11:00 B23
ADWN 3009 12:00 B19
DDWN 723 11:30 B04
ADWN 1589 14:20 B12
ADWN 1259 11:10 B23
DDWN 2534 13:00 B16
ADWN 3009 11:50 B14
This gives me all matches:
grep '1259\|3009\|1589' somelog.log
And this gives me only the first match
grep -m 1 '1259\|3009\|1589' somelog.log
I want to return the following:
ADWN 1259 11:00 B23
ADWN 3009 12:00 B19
ADWN 1589 14:20 B12
I think that creating a file with the required values, and then looping through the file, passing each number individually into the grep command will give me what I am looking for, but I haven't found an example of this. Is there a simple solution for this, is a loop the best way to handle this, or has this example already been answered elsewhere?
Thanks in advance for your ideas and suggestions--
Clyde
Using head To Limit grep Output It's still a little useful to use -m 1 with grep though, as it will stop processing large files if a match is found early. This works with the -o flag to print only the first match, even if there are multiple matches in a file: However, be careful when using this with multiple files.
To search multiple files with the grep command, insert the filenames you want to search, separated with a space character. The terminal prints the name of every file that contains the matching lines, and the actual lines that include the required string of characters. You can append as many filenames as needed.
To also show you the lines before your matches, you can add -B to your grep. The -B 4 tells grep to also show the 4 lines before the match. Alternatively, to show the log lines that match after the keyword, use the -A parameter. In this example, it will tell grep to also show the 2 lines after the match.
One way using awk
:
awk '!array[$2]++ && $2 ~ /^1259$|^3009$|^1589$/' file.txt
Results:
ADWN 1259 11:00 B23
ADWN 3009 12:00 B19
ADWN 1589 14:20 B12
edit:
I should really get into the habit of reading the whole question first. I see that you're thinking of creating a file with the values you'd like to find the first occurrence of. Put these in a file called values.txt
with one value per line. For example; here's the contents of values.txt
:
1259
3009
1589
Then run this:
awk 'FNR==NR { array[$0]++; next } $2 in array { print; delete array[$2] }' values.txt file.txt
Results:
ADWN 1259 11:00 B23
ADWN 3009 12:00 B19
ADWN 1589 14:20 B12
1st command explanation:
If the second column ($2
) equals one of those three values listed, add it to the array if it's not already in there. awk
prints the whole line by default.
2nd command explanation:
FNR
is number of records relative to the current input file.NR
is the total number of records.
The FNR==NR { ... }
construct is only true for the first input file. So for each of the lines in values.txt
, we add the whole line ($0
) to an array (I've called it array, but you could give it another name). next
forces awk
to read the next line in values.txt
(and skip processing the rest of the command). When FNR==NR
is no longer true, the second file in the arguments list is read. We then check for the second column ($2
)in the array, if it's in there, print it and remove it from the array. By using delete
we essentially set a max count of one.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With