LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Newbie (https://www.linuxquestions.org/questions/linux-newbie-8/)
-   -   find all matching lines before first matc (https://www.linuxquestions.org/questions/linux-newbie-8/find-all-matching-lines-before-first-matc-4175524351/)

ani78 11-04-2014 06:32 PM

find all matching lines before first matc
 
I am trying to print all the lines from a file before the first match. I have the same entries again in the file, but I don't need that lines.
Tried awk "{print} /${pattern}/ {exit}" and sed "/$pattern/q" (my serach is based on a variable). But both these commands are printing all the line before the last match
ex: my file is like
abc
bcd
def
xyz
def
lmno
def
xvd

when my pattern is 'def', i just need abc and bcd . but the above commands are printing, all the lines before the last 'def'. could you please provide some idea

grail 11-04-2014 07:01 PM

I am not sure I follow the issue as using your too codes I get exactly the same output and only up to the first occurrence:
Code:

$ awk '{print}/def/{exit}' file
abc
bcd
def
$ sed '/def/q' file
abc
bcd
def

Now to nme this is not quite the brief as it also prints the pattern being searched for and your example seemed to imply this was not desired.
However, as you can see I do not print any further than the first occurrence.

syg00 11-04-2014 07:12 PM

But the OP wants to use a bash (?) variable. The same logic error applies regardless.
The posted sed should work - maybe we need to know more about sed and Linux version.

AFAIK awk needs the variable assigned with -v before it is available for processing (grail, is this true ?). But again the posted code is remiss.

grail 11-05-2014 12:20 AM

Yes awk is not fond of double quotes and it makes life more complicated if you actually need to start writing strings in your code.

So you can either use -vpat="$pattern" as suggested or after last quote and prior to calling files you could do pat="$pattern":
Code:

awk '{print}$0 ~ pat{exit}' pat="$pattern" file

ani78 11-05-2014 04:27 PM

Thanks Grail,

Interesting... when I tried to execute the same command, its giving all the entries upto the last match

I am trying to get the user access details for the last 10 days using the output of the "last" command. If I try to find the access until Oct 25 (2014), its showing all entries until Oct 25 (2013). As "last" is not showing the year, I can't provide that information.

I am using teh command "perl -le 'print scalar localtime (time() - 240*60*60);' |awk '{print $2 ,$3 }'" to find the month and date, assign that to a variable and then using sed/awk to get the details

suicidaleggroll 11-05-2014 04:39 PM

Here it is with grep

Code:

nlines=$(cat $file | wc -l)
grep -B $nlines -m 1 $pattern $file

nlines gets the number of lines in the file
-B $nlines tells grep to print that many lines before each match (setting this to nlines means it can print up to the entire file, if the only match is on the last line)
-m 1 tells grep to only return one (the first) match

rknichols 11-05-2014 05:47 PM

Here is a solution with sed:
Code:

sed -n "/$pattern/q;p"
Suppress the automatic printing, quit if there is a match, then an explicit print of any line that did not match. Note that the sed manpage does say that you have to suppress the automatic print to avoid printing the line that triggered the "q" command.

Like the others who have posted, I cannot duplicate the behavior of continuing until the last pattern match. Perhaps the output from your last command has some non-printing characters or whitespace differences that are causing the first match to fail.

grail 11-05-2014 06:57 PM

So I am curious now, with the additional information, why you do not simply perform all the tasks in Perl? It can easily perform all the tasks of sed/awk/grep and you have already stepped into it to perform a trivial
task.

ani78 11-06-2014 04:38 PM

Thanks everyone

Unfortunately I am not at all good in perl :(

Looks like the issue was with the format of the date format I am extracting using the perl command is not matching with 'last' command date format. Replaced all the spaces with a single # and seems its working now

Thanks again

grail 11-06-2014 06:42 PM

Glad you finally have a solution. Please remember to mark question as SOLVED


All times are GMT -5. The time now is 11:18 AM.