Awk script into Perl

Hello,

I have not programmed in Perl, but maybe someone can help me or point me to other links. I have searched for and found a solution to my initial problem. I have a text file of data where I want to search for a particular string but return the prior line. I found out here something that worked great (with a small test file)...

cat myfile.txt | awk '{ x[NR] = $0 } END { for ( i=1; i<=NR; i++ ) { if (x ~ /my_search_string/ ) print x[i-1] }} ' >> $filedir/$myoutput

However, I did not realize there was a 3000 character limit on the awk command, so when I input an extremely wide file (like 50,000+ characters in 1 line), this is failing. So, everyone said to switch to gawk/GNU awk. We do not have gawk here, and for security reasons, I do not have permission to download or install gawk on our HP-UX and/or Sun Solaris boxes.

Can this be easily re-written into a Perl script? And can Perl handle extremely wide files?

Thanks,
Brian

Am I getting you right, if the string you're searching for is in line 43, you want to print line 42, right? If so (untested):

awk 'BEGIN{prev=""} /search_string/{print prev} {prev=$0}' myfile.txt
perl -ne 'print $prev if /search_string/; $prev=$_;' myfile.txt

For more complex stuff, take a look at a2p, part of any Perl distribution.

If you want to return just one prior line using Perl, then pludi's Perl script is extremely efficient.

Here's a variation though, but the underlying concept is the same - print variable p when string matches and then save the current line to variable p.

$
$ cat -n f5
     1  aaaaaaa THIS IS LINE_1 aaaaaaa
     2  bbbbbbb THIS IS LINE_2 bbbbbbb
     3  ccccccc THIS IS LINE_3 ccccccc
     4  ddddddd THIS IS LINE_4 ddddddd
$
$ perl -lne '/LINE_3/ && print $p; $p=$_' f5
bbbbbbb THIS IS LINE_2 bbbbbbb
$
$

By the definition of your problem, it won't print anything if you match "LINE_1" in the file above.
And you'll never be able to print the last line either.

$
$ perl -lne '/LINE_1/ && print $p; $p=$_' f5
$
$ perl -lne '/LINE_4/ && print $p; $p=$_' f5
ccccccc THIS IS LINE_3 ccccccc
$

I created a dummy file very similar to f5 above, but with each line containing 1,000,000 characters (1 million). And the script worked fine. Even with the search string being at the very end of the 1-million character line.

I'll leave it for you to decide. :wink:

The idea here is to save the entire line in a single Perl variable ($p above or $prev in pludi's script).
Perl imposes no limitation on the length of a string variable. It is limited only by your system's memory.

Here's an excerpt from the Perl man page:

...
Unlike most Unix utilities, Perl does not arbitrarily limit the size of your data--if you've got the memory,
Perl can slurp in your whole file as a single string.
...

HTH,
tyler_durden

Tyler_durden and pludi,

Thanks for your replies. This is working for me now.

Thanks,
Brian