On Fri, 4 Oct 2002, waytech wrote:

> hi everyone,
> 
>     Thanks for all replys about my question.
> 
>  I know here are lots of  perl experts.
> 
>  it's amazing that someone can short
> 
> that long program into one line.
> 
>     I am a  perl newbie, i wonder
> 
> whether someone can  explain  what
> 
> these guys wrote(like what
> 
> Sudarshan Raghavan wrote
> 
> ). I really can not understand.
> 
>     Since this group called " perl beginners",
> 
> i hope i can get some explanations.
> 
> Tanks a lot.
> 
>                              kevin

I will explain the one-liners in the order in which they were posted

1) perl -e'while(<>){print unless $seen{$_}++}' <infile >outfile

-e command line switch: Type perldoc perlrun and read about the -e option.

<> (diamond operator): perldoc perlop, search for 'The null filehandle'

print unless $seen{$_}++ is the same as
unless ($seen{$_}++) {
    print;
}

2) perl -n -e 'print unless $seen{$_}++' infile >outfile

Removed the while (<>) {} wrapper from the first one. The -n command line 
switch will do this for us.
perldoc perlrun # -n switch

3) perl -ne'$s{$_}++||print' infile >outfile

Same as 2, $s{$_}++||print works like this, the print statement is 
executed only if $s{$_}++ evaluates to false (lazy evaluation).
It is the same as

while (<>) {
  unless ($s{$_}++) {
    print;
  }
}

4) perl -pe'$+{$_}++&&y+++cd' infile >outfile

# perldoc perlrun for the -p switch

%+ is the hash used here instead of %s or %seen used in the above examples.
If $+{$_}++ evaluates to true then execute y+++cd (lazy evaluation again)
y+++cd is nothing but y///cd or tr///cd, using '+' as a delimiter instead 
of '/'
 
The above one-liner can be written as
while (<>) {
  if ($+{$_}++) {
    tr///cd;
  }
  print;
}

For y/// or tr///: perldoc perlop # Search for Quote-like Operators 

5) perl -pe'$s{$_}++&&s{.+}$$s' infile >outfile
Borken down to

while (<>) {
  if ($s{$_}++) {
    s{.+}$$s; # same s/.+//s;
  }
}

/s modifier makes '.' match on a newline too (by default it does not)
perldoc perlre

When matching delimiters like '{' and '}' are used to enclose the left 
hand side of s/// or tr///, you can use another pair or character to 
enclose the right hand side. In this case the character '$' is used to 
enclose the RHS.

6) perl -pe'$s{$_}++&&s{$_}++' infile >outfile

Same as above, using '+ to enclose the RHS instead of '$'. Note this will 
not work if any regex metacharacters are a part of $_ (the line read in).
You can overcome this by using \Q and \E. perldoc perlre




-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to