Beefy Boxes and Bandwidth Generously Provided by pair Networks
There's more than one way to do things

sed awk to perl help

by Anonymous Monk
on Apr 17, 2007 at 08:12 UTC ( #610478=perlquestion: print w/replies, xml ) Need Help??
Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Oh Holy ones, I'm trying to convert a piece of shell,sed, and awk script into the chosen language. Unfortunalty, I'm still learning the chosen language, and am a bit stumped. The script breaks a line on either a : or ; and turns that into a url link. I was wondering if someone might be able to assist:
cat page.txt | sed 's/;/\n/g'| sed 's/:/\n/g'|awk {'print "<a href=mys"$1" >"$1"</a>"'}
I started with something like this but soon got stuck trying to chain sed command together
out=~s/;/\n/; out=~s/:/\n/; print "<a"$out" >"$out"</a>";
Any ideas?
Thank you

Replies are listed 'Best First'.
Re: sed awk to perl help
by Corion (Pope) on Apr 17, 2007 at 08:42 UTC

    You're on the right track already, except that variable names in Perl are prefixed by a sigil - $ is the sigil for a single value, while @ is the sigil for an array/a list, and % is the sigil for a hash ("associative array" in awk).

    For a start, I'd just convert the stuff behind the cat invocation verbatim which is the trickier part:

    use strict; # Read from standard input while (<>) { s/;/\n/g; # this is just like sed s/:/\n/g; # this is just like sed # Now, split the input line on newlines, like awk will do: my @pages = split /\n/; for my $page (@pages) { # I'm using qq{...} instead of double quotes (") # so I don't have to escape the stuff in ugly ways print qq{<a href="$page">$page</a>\n}; }; };

    To convert the two verbatim sed commands and the awk command into one thing that just takes everything that is delimited by ; or : and prints out a HTML link to it, I'd rewrite the loop as follows:

    use strict; # Read from standard input while (<>) { # Remove the newline at the end of $_ chomp; # Split the input line on ":" or ";": my @pages = split /[:;]/; for my $page (@pages) { # I'm using qq{...} instead of double quotes (") # so I don't have to escape the stuff in ugly ways print qq{<a href="$page">$page</a>\n}; }; };

    Update: Replaced my erroneous use of $1 with $page, which is the correct variable to use. Thanks, johngg!

      Perhaps I'm missing something but how is the $l (or is it $1) in the print statements getting initialised. Maybe it should be $page in each case?



Re: sed awk to perl help
by Limbic~Region (Chancellor) on Apr 17, 2007 at 10:34 UTC
    Anonymous Monk,
    Beyond the advice you have already been given, your perl should have shipped with a s2p and a2p utility. Even if you do not use the resulting code, it should give you a good idea of one way to do it.

    Cheers - L~R

Re: sed awk to perl help
by Moron (Curate) on Apr 17, 2007 at 15:48 UTC
    For replacing this type of "one-liner" shell processing containing invocations of awk and sed with equivalent Perl code, I strongly suggest looking at perlrun. In this example it becomes something like:
    perl -pipage.txt -ea -F"[;:]" 'my $out=shift @F;print "<a href=mysite. +net/$out>$out</a>\n";'

    ^M Free your mind!

      When I tried this example, I had some problems with it, and I think there are 2 issues:

      1) the order of the arguments (I needed to order them as perl -paipage.txt -F"[;:]" -e to avoid the error

      Can't open my $out=shift @F;print "<a$out>$out</a>\n" +;: No such file or directory.

      and 2), the script didn't seem to handle multiple matches on the same line (that I think the original did)

      'map { print "<a$_>$_</a>\n" } @F'

      then I realized that this still didn't handle the way that awk deals with white space, so the one line got longer when I added split(" ",$_)

      perl -F"[:;]" -lane 'map { ($_)=split " ",$_; print "<a +t/$_ >$_</a>" } @F'

      given test data like

      a b ; d e : f g : ; x
        the -F specifies the split pattern, so instead of also splitting by ' ', just change the -F argument to  -F"[:;\s]"

        ^M Free your mind!

        Key to hats: ^I=white ^B=black ^P=yellow ^E=red ^C=green ^M=blue - see Moron's scratchpad for fuller explanation.

Re: sed awk to perl help
by xicheng (Sexton) on Apr 18, 2007 at 05:10 UTC
    From your pipe line, I guess you actually want to grab the first 'word' (any continuous non whitespaces|simicolon|colon, like [^\s;:]+) after the start of a newline '^' or any colon|simicolon characters. This can be done pretty easily by a regex, not necessarily a better way, just another option for you:
    perl -wlne '
        my @sites = /(?:^|[;:])\s*([^\s:;]+)/g;
        print qq(<a href="$_" >$_</a>) for @sites;
    ' page.txt

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://610478]
Approved by Corion
Front-paged by Corion
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others drinking their drinks and smoking their pipes about the Monastery: (7)
As of 2016-10-22 09:14 GMT
Find Nodes?
    Voting Booth?
    How many different varieties (color, size, etc) of socks do you have in your sock drawer?

    Results (294 votes). Check out past polls.