Re: String Search/Replace
by Fletch (Bishop) on Aug 31, 2005 at 14:32 UTC
|
perl -lane 'for(@F[1..4]){$_=0if$_>1000};print"@F"'
Update: Shave a couple of strokes.
perl -lape 'for(@F[1..4]){$_=0if$_>1000};$_="@F"'
--
We're looking for people in ATL
| [reply] [d/l] [select] |
|
|
| [reply] |
Re: String Search/Replace
by ikegami (Patriarch) on Aug 31, 2005 at 14:24 UTC
|
Zillion? How about only one:
perl -ple "@f=split; for(@f[1..4]){ $_=0 if $_>1000 } $_=qq{@f}" infil
+e >outfile
or in-place:
perl -i.bak -ple "@f=split; for(@f[1..4]){ $_=0 if $_>1000 } $_=qq{@f}
+" file
Update:
Better yet, -a saves us the trouble of splitting:
perl -lape "for(@F[1..4]){ $_=0 if $_>1000 } $_=qq{@F}" infile >outfil
+e
or in-place:
perl -i.bak -lape "for(@F[1..4]){ $_=0 if $_>1000 } $_=qq{@F}" file
perlrun documents -i, -l, -a, -p and -e.
The command can be written in fewer strokes, but I left it readable.
| [reply] [d/l] [select] |
|
|
Hm... I tried the first in your original post and your updated, both give the same error. I check, and the file I'm using is definatly writable.
bash-2.05$ perl -ple "@f=split; for (@f[1..4]) { $_=1000 if $_>1000; }
+ $_=join(' ',@f)" TEST
Can't modify constant item in scalar assignment at -e line 1, near "10
+00 if"
Execution of -e aborted due to compilation errors.
bash-2.05$ perl -lape "for(@F[1..4]){ $_=1000 if $_>1000 } $_=qq{@F}"
+TEST
Can't modify constant item in scalar assignment at -e line 1, near "10
+00 if"
Execution of -e aborted due to compilation errors.
Did I do something wrong?
-Jack C
jack {@} crepinc.com
http://www.crepinc.com/ | [reply] [d/l] |
|
|
I'm using quoting appropriate for the Windows shell. Substitute " for ' and vice-versa for unix shells.
| [reply] [d/l] [select] |
|
|
Re: String Search/Replace
by gargle (Chaplain) on Aug 31, 2005 at 14:38 UTC
|
Hi,
Many answers already, but, if you're looking to split up the numbers in variables:
#!/usr/bin/perl
use strict;
use warnings;
while (<DATA>) {
chomp;
my ($a, $b, $c, $d, $e) = split/ /;
print "$a $b $c $d $e\n";
}
__DATA__
1125356700 0 0 0 0
1125356400 15 0 25 0
1125356100 25 0 25 0
1125355800 25 0 25 0
1125355500 25 0 25 0
1125397800 0 0 0 0
1125397500 0 0 0 0
1125397200 0 0 0 0
1125396900 0 0 0 0
1125396600 0 0 0 0
1125396300 0 0 0 0
1125396000 39006 0 63597 0
1125395700 63597 0 63597 0
1125395400 63597 0 63597 0
1125395100 63597 0 63597 0
1125394800 63597 0 63597 0
1125394500 63597 0 63597 0
1125394200 63597 0 63597 0
--
if ( 1 ) { $postman->ring() for (1..2); }
| [reply] [d/l] |
Re: String Search/Replace
by philcrow (Priest) on Aug 31, 2005 at 14:40 UTC
|
I like golf about as much as the next person, but how about something a bit more expansive:
#!/usr/bin/perl
use strict;
while (<>) {
my ($timestamp, $number, @rest) = split;
$number = 0 if ($number > 1000);
print "$timestamp $number @rest\n";
}
The solutions above work in place. This one is a filter. To use it do something like this:
./filter < input > output
But don't make output the same as input or the shell will kill your data.
Phil | [reply] [d/l] [select] |
Re: String Search/Replace
by ChrisR (Hermit) on Aug 31, 2005 at 15:07 UTC
|
#!c:\perl\bin\perl.exe -w
use strict;
use warnings;
for my $line (<DATA>)
{
$line =~ s/ \d{4,}( |$)/ 0$1/g;
print $line;
}
__DATA__
1125356700 0 0 0 0
1125356400 15 0 25 0
1125356100 25 0 25 0
1125355800 25 0 25 0
1125355500 25 0 25 0
1125397800 0 0 0 0
1125397500 0 0 0 0
1125397200 0 0 0 0
1125396900 0 0 0 0
1125396600 0 0 0 0
1125396300 0 0 0 0
1125396000 39006 0 63597 0
1125395700 63597 0 63597 0
1125395400 63597 0 63597 0
1125395100 63597 0 63597 0
1125394800 63597 0 63597 0
1125394500 63597 0 63597 0
1125394200 63597 0 63597 0
Or for a one liner:
perl.exe -ple "s/ \d{4,}( |$)/ 0$1/g" filename
Update:
Oops... As cheseter has pointed out, the above will replace 1000 when it should not.
Here's my regex that works:
$line =~ s/ (\d+)/$1>1000?" 0":" $1"/ge;
or at least I think it does. | [reply] [d/l] [select] |
|
|
perl -ple "s/ \d{4,}/ 0/g" infile >outfile
| [reply] [d/l] [select] |
|
|
Thanks. I didn't think about that. I've never been very good at golf (perl or otherwise).
| [reply] |
|
|
| [reply] [d/l] |
|
|
Actually doesn't the original question say to replace numbers "over 1000" with 0? Your solution also replaces 1000 with 0, which would be incorrect.
| [reply] |
|
|
Err... You've got me there. I think you should remove the strike from your previous post. Your solution is the shortest since it appears that mine is incorrect.
| [reply] [d/l] |
|
|
Hi,
I really do love regex's but sometimes, when only used to cut up a string in pieces, pieces seperated by the same character, I prefer to use split. Reading the code becomes a bit easier on the eyes because you can immediately deduct the meaning of the line of code. With regex's you still have to do a bit of mental juggling before the intention becomes clear.
--
if ( 1 ) { $postman->ring() for (1..2); }
| [reply] |
Re: String Search/Replace
by chester (Hermit) on Aug 31, 2005 at 14:57 UTC
|
Without using split (I think this is the shortest so far too...):
perl -ple "s/(?<!^)\b(\d+)/$1>1000?0:$1/eg" filename
edit: Nope, see below. :)
edit2: Never mind... | [reply] [d/l] [select] |
Re: String Search/Replace
by sh1tn (Priest) on Aug 31, 2005 at 14:49 UTC
|
perl -lape 's/\S+\s+//&&s/(\d+)/$1>1000?0:$1/ge' filename
Update: ok this (even shorter) does not remove the timestamp:
perl -pe 's/(?<=\s)(\d+)/$1>1000?0:$1/ge' filename
| [reply] [d/l] [select] |
|
|
That removes the timestamp.
| [reply] |