Beefy Boxes and Bandwidth Generously Provided by pair Networks
Think about Loose Coupling

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
[marto]: so I have to work Saturday, which is good and bad. Bad in the sense that I have to be hear early :( Good in that I am here only as support for another client project, so I get to spend the day working on my personal 'ToDo' list, without the kids :P
[Corion]: marto: Ooof - but yes, being there as only second level support or third level support is good and if you have enough things that you can work on, it won't be a wasted (if paid) day
[marto]: I've opted for a day off later on, rather than pay. I only have to do about 45 mins work for the client, but do need to hang around
[Corion]: marto: Even better ;)

How do I use this? | Other CB clients
Other Users?
Others studying the Monastery: (5)
As of 2017-02-28 10:08 GMT
Find Nodes?
    Voting Booth?
    Before electricity was invented, what was the Electric Eel called?

    Results (399 votes). Check out past polls.