Re: how to delete part of the line?
by ikegami (Patriarch) on May 21, 2009 at 21:06 UTC
|
perl -ple's/^line\d+=//' infile > outfile
Use double quotes in Windows.
Update: Oops, I forgot about the slashes. That should be
perl -nle's/^line\d+=//; push @l,$_; END { $,=q{/}; print @l }' infile
+ > outfile
Not nearly as nice a one-liner :(
| [reply] [d/l] [select] |
|
|
perl -ple's/^line\d+=//' infile | perl -p0e 's!\n!/!g' > outfile
or
perl -ple's/^line\d+=//' infile | perl -p0e 's!\s+$!! ; s!\n!/!g' > ou
+tfile
if end of the output has any meaning. Hmm, seems there is no beauty, too. | [reply] [d/l] [select] |
|
|
perl -pl57e"s/^line\d+=//" infile > outfile
| [reply] [d/l] |
|
|
where do I insert this in my code?
| [reply] |
|
|
That's the code in its entirety.
| [reply] |
Re: how to delete part of the line?
by akho (Hermit) on May 21, 2009 at 21:07 UTC
|
General advice: use strictures and the 3-argument form of open. Something like this:
use strict;
use warnings;
open my $in, '<', 'infile';
open my $out, '>', 'outfile';
my @values;
while (my $line = <$in>) {
chomp $line;
my ($value,) = $line =~ /^line\d+=(.+)/;
push @values, $value if (defined $value);
}
print $out join('/', @values);
close $in;
close $out;
| [reply] [d/l] |
Re: how to delete part of the line?
by bichonfrise74 (Vicar) on May 21, 2009 at 21:39 UTC
|
#!/usr/bin/perl
use strict;
s/line\d+=(.*)// and print "$1\n" while (<DATA>);
__DATA__
line1=10
line2=30
line3= I am a monk
line4=true
| [reply] [d/l] |
|
|
Minor niggle: bichonfrise74: At line 5, didn't you mean "...and print "$1/" while...?
This scales nicely (as do the other replies above) for a source file (which OP calls a "result file") which includes only elements of a single data set. But IMO, the actual problem is likely under-spec'ed.
Yes, I may be overthinking this but I can't help but wonder if we're giving the "X" answers where what OP is seeking may be the "Y" answers, but isn't getting them because the problem is less than fully stated.
Here's my train of thought: it seems to me that the phrase "result file" may imply that it contains sets of (previously selected) data from multiple sources (multiple rows of a DB table, for example) in which case one might expect that there will be a delimiter - - express or implied - - between the sets.
OP's ellipsis beg the question.
Suppose the source looks like this:
__DATA__
line1=10
line2=30
line3= I am a monk
ine4=false
line5=20
line6=42
line7= But I haven't read perlretut and I should have!
line8=true
line8=34
line9=67
line10=Coder
line11=false
Is this one set of 12 items or three sets of 4 items each. And what if the data continues with an inconsistent set such as:
line12=00
line2=11
line3=
line4=questionable
Hence, yskmonk, you may wish to enlighten us with details. Did one of the fine answers above solve your problem or does your question need refinement/more specifics?
Update: If the original question (data has since undergone a major transformation, which is still insufficiently particular) relates to sets of data, each comprising 4 lines, then one answer might be:
my @outfile = (
"line1=10",
"line2=30",
"line3= I am a monk",
"line4=false",
"line5=20",
"line6=42",
"line7= But I haven't read perlretut and I should have!",
"line8=true",
"line8=34",
"line9=67",
"line10=Coder",
"line11=false",
);
my @quads;
while (@outfile) {
my $line;
for (1..4) { # presumption: each data set is made up
+of 4 consecutive lines *
my $line_from_outfile = shift (@outfile);
$line_from_outfile =~ /line\d+=(.*)/;
$line .= $1 . "/" ;
}
push @quads, $line;
$line = "";
}
for my $quad(@quads) {
print $quad . "\n"; # to console; writing to file "final.txt" is
+left as an exercise for OP
}
* Season Line 19 to taste. | [reply] [d/l] [select] |
Re: how to delete part of the line?
by yskmonk (Initiate) on May 22, 2009 at 03:01 UTC
|
I am still stucks guys...
here is what I am doing:
my result.txt file has final output and it looks like below:
blah1.blah1.blah1=10
blah2.blah2.blah2=0
bhal3.blah3.blah3=false
here is my code after I get the result.txt file:
my $value = "value.txt" ;#final file I want with output as 10/0/false
open RESULT, "<$result";
open VALUE, ">$value";
s/line\d+=(.*)// and print "$1/" while (<RESULT>);
close VALUE;
close RESULT;
am I doing anything wrong?
Please help! | [reply] [d/l] [select] |
|
|
Yes! You are doing several things "wrong."
Just for starters, you can't simply plug someone else's regex (cf: Cargo Cult) into an script to process utterly unrelated data and expect it to be anything other than "wrong."
Your (borrowed) substitution looks for the word "line" followed by one-or-more digits, followed by anything, capturing the last of those. That's not the way your latest version of the data is structured. Since there isn't the word "line" anywhere in the data, the regular expression never matches.
As linuxer advises "(p)lease see perlretut, perlrequick and perlre for more information about regular expressions."
And to repeat myself, you need to be a great deal more precise in stating the problem. The use of "blah1.blah1.blah1" and so on as a stand-in for some actual data may be adequate to solve the question you asked, but is likely insufficient for us to provide help that will assist you to solve whatever your actual problem may be.
| [reply] |
|
|
Where do you print the output to the output file?
why can't you use chomp on input lines?
watch other monk's replies to your post and experiment those, and chose the one which suits you.
never go by the one liner method, it is not good for large programs, monks who showed those one liners actually wanted to say that your part of the requirement can be solved easily by those methods, it is not necessary that you have to follow that one liner method in your program, just understand that logic behind the one liner, and use it carefully at appropriate places inside your program.
Vivek
-- In accordance with the prarabdha of each, the One whose function it is to ordain makes each to act. What will not happen will never happen, whatever effort one may put forth. And what will happen will not fail to happen, however much one may seek to prevent it. This is certain. The part of wisdom therefore is to stay quiet.
| [reply] |
|
|
This may not be the best suggestion, but I can think of two ways to do this.
At the unix command line: cat result.txt | cut -d"=" -f2 | sed 's/^ \t*//;s/ \t*$//' | tr "\n" "/"
perl:
#!/usr/bin/perl
use strict;
use warnings;
while (chomp(my $line=<>)) {
my (undef,$value)=split/=/,$line);
$value =~ s/^\s+|\s+$//g;
print "$value/";
}
| [reply] [d/l] |
|
|
A regular expression line\d+= won't match with a text "blah1,blah1,blah1=".
You must adjust your regular expression, so it can match your 'blah...' string.
Please see perlretut, perlrequick and perlre for more information about regular expressions.
And you must print to your output handle, if you want the result in value.txt. Currently you are printing to STDOUT; see print
| [reply] [d/l] [select] |
Re: how to delete part of the line?
by linuxer (Curate) on May 22, 2009 at 00:50 UTC
|
Instead of deleting the unwanted part, you could split each line into parts and just use the wanted part.
#! /usr/bin/perl
use strict;
use warnings;
my $in_file = 'input.txt';
my $out_file = 'output.txt';
my @result;
open my $handle_in, '<', $in_file or die "$in_file: $!";
while ( <$handle_in> ) {
# split (into 2 parts) at = (enclosed in optional whitespaces)
# use the last part and store it in @result
push @result, ( split( /\s*=\s*/, $_, 2 ) )[-1];
}
close $handle_in;
# remove line breaks from array elements
chomp @result;
open my $handle_out, '>', $out_file or die "$out_file: $!";
# print elements (ignore undefined and empty ones)
print $handle_out join( '/', grep { defined && length > 0 } @result )
or die "$out_file: $!";
close $handle_out or die "$out_file: $!";
__END__
Considering ww's message you might need to add more checks and logic to match more complicated input files.
| [reply] [d/l] |