Link to home
Start Free TrialLog in
Avatar of bt707
bt707Flag for United States of America

asked on

perl one liner

I have a file that has groups of lines, I need to print out certain groups of lines if they contain a key word.
I usally do this with a one liner like.

perl -n00e 'print if /key_word/i' file1.txt

I need to do the same thing but use a text file that contains a long list of key words, how do I make x=(the key_words in file1.txt) then do something like

perl -n00e 'x=(key words in file1.txt;print if /$x/i' file2.txt


I tried something crazy like this but it prints out everything, not even close to what I'm trying to do.

for i in file1.txt; do perl -n00e 'print if /$i/i' file2.txt; done

Thanks,
Avatar of bt707
bt707
Flag of United States of America image

ASKER

I tried to do a

cat file1.txt  then add a while (<>);

but still not getting it to work, how can I do this from a one liner and in a small script.

Thanks,
Avatar of FunnyMan
FunnyMan

Here's a script for you.  It takes two "files" of input, separated by an EOF marker (Ctrl-D on a blank line if doing it interactive).  Probably don't want to do it as a one-liner, but you could if you really wanted to.

$search = "(";
$first = true;
while ($line = <>)
{
  chomp($line);
  $search = "$search$line|";
}
chop($search);
$search = "$search)";
while ($line = <>)
{
  print $line if ($line =~ m/$search/i)
}

-FM
Does it have to be done in perl?
for line in `cat file1.txt`; do grep -i $line file2.txt; done
The above line prints:
this is a test
please stop

file1 contains:
test
stop

file2 contains:
this is a test
do nothing
st
please stop
Avatar of bt707

ASKER

hi Morcalavin,

for what I need I think I need perl, I'm not just doing a grep for a line that contains a keyword which is what your command would do, that would work fine for that but what I need is to pull a section out if it contians the key word.

In the file2.txt it contains sections with about 20 lines which each section is seperated by a blank line, the perl -00 let me read section in paragraph mode and if any of the sections contain a key word then it pulls out the whole section.

I can do it one at a time with  # perl -n00e 'print if /key_word/i' file2.txt    but want to be able to feed it multiple words to look for, the solution from FunnyMan may work but I can't seem to figure that one out.

Thanks,
grep -p pulls out of paragraph using empty lines as delimiters:

for line in `cat file1.txt`; do grep -ip $line file2.txt; done
The above line prints:
this is a test line.  it should not end
here it should end

this is a stop line
here it should end



file2:
this is a test line.  it should not end
here it should end

this is a stop line
here it should end

hi there
why hello!
Avatar of bt707

ASKER

where are you getting the -p option? I'm on a solaris 9 box, maybe that option with grep is on linux? not sure but I've never seen that option and don't have it.
Would be nice to have.
I have it on my AIX boxes and Linux.

Your version of grep doesn't have a -p option?  What a drag.  You can use -p to separate at a blank line, or provide your own delimeter.
Avatar of bt707

ASKER

no don't have it here with Solaris, sure would be nice to have though.
Avatar of ozo
perl -ne 'if( $/ ){ local @ARGV=(); chomp(@_=<>); $x=join"|",@_; $x = qr/$x/i; $/=""; } print if /$x/' file1.txt file2.txt
Avatar of bt707

ASKER

That worked ozo, but have one problem that I didn't think about, some of the groups of records contains the names that I'm searching for but do not want those records.

I only want the records if they contain the user name I'm looking for in file1.txt and it starts at the first of line one.  anytime the name is found in a record that I don't want it does not start the line so I just need to make it say the user names in file1.txt must start a line.

I tried changing to print if /^$x/ but obviously that didn't get what I needed. how can I print out only if the names in file1.txt are found at the begging of a line.

Thanks,
ASKER CERTIFIED SOLUTION
Avatar of ozo
ozo
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of bt707

ASKER


I must of put something in wrong, it's printing the whole file2 and all on one line, here is what I tried.

perl -ne 'if( $/ ){ local @ARGV=(); chomp(@_=<>); $x=join"|",map{"^$_"}@_; $x = qr/$x/is; } print if /$x/' file1.txt file2.txt
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of bt707

ASKER

Thanks manav, I finally did see where I had missed part of the command ozo gave, the command ozo posted all worked fine as usual, I had forgot to go back and close the question.

Thanks for pointing that out.