LinuxQuestions.org
Review your favorite Linux distribution.
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 02-04-2010, 10:14 AM   #1
hawk__0
Member
 
Registered: Nov 2008
Posts: 105

Rep: Reputation: 15
Using Perl, how do I chomp every 2nd line?


I'm trying to chomp the new line character off of every 2nd line in a CSV file but I'm a little stuck.

Code:
#!/usr/bin/perl
use strict;
use warnings;

chomp(my $file = $ARGV[0]);
open (FILE, ">$file") or die "Error: $!";
while(<FILE>){
chomp($_);
}
The above code gives me this error:
Code:
 perl SCR.pl TEST.TXT
Filehandle FILE opened only for output at SCR.pl line 7.
 
Old 02-04-2010, 10:20 AM   #2
TB0ne
LQ Guru
 
Registered: Jul 2003
Location: Birmingham, Alabama
Distribution: SuSE, RedHat, Slack,CentOS
Posts: 26,553

Rep: Reputation: 7946Reputation: 7946Reputation: 7946Reputation: 7946Reputation: 7946Reputation: 7946Reputation: 7946Reputation: 7946Reputation: 7946Reputation: 7946Reputation: 7946
Quote:
Originally Posted by hawk__0 View Post
I'm trying to chomp the new line character off of every 2nd line in a CSV file but I'm a little stuck.

Code:
#!/usr/bin/perl
use strict;
use warnings;

chomp(my $file = $ARGV[0]);
open (FILE, ">$file") or die "Error: $!";
while(<FILE>){
chomp($_);
}
The above code gives me this error:
Code:
 perl SCR.pl TEST.TXT
Filehandle FILE opened only for output at SCR.pl line 7.
Not surprising..you're opening the file for output, as your error states. Remove the ">" character, and you'll be opening it for input.
 
Old 02-04-2010, 10:38 AM   #3
hawk__0
Member
 
Registered: Nov 2008
Posts: 105

Original Poster
Rep: Reputation: 15
Okay, I had it as "<" previously (for reading, right?). Now if I run the script, nothing is chomped!

Code:
steve@steves-desktop:~$ perl SCR.pl TEST.TXT
steve@steves-desktop:~$ cat TEST.TXT 
1
2
3
4
 
Old 02-04-2010, 10:38 AM   #4
hawk__0
Member
 
Registered: Nov 2008
Posts: 105

Original Poster
Rep: Reputation: 15
Scratch that, I got it working... sort of. I need to now know how to chomp every OTHER line. Here is my current code:
Code:
#!/usr/bin/perl
use strict;
use warnings;

chomp(my $file = $ARGV[0]);
open (FILE, "$file") or die "Error: $!";
while(<FILE>){
print "Chomping " . $_ . "\n";
chomp $_;
}
close FILE;
edit: Now it's not working WTH!? What does chomp remove? CR? LF? CR/LF?

Would this have anything to do with the fact that it's a CSV file?

Last edited by hawk__0; 02-04-2010 at 01:14 PM.
 
Old 02-04-2010, 01:20 PM   #5
TB0ne
LQ Guru
 
Registered: Jul 2003
Location: Birmingham, Alabama
Distribution: SuSE, RedHat, Slack,CentOS
Posts: 26,553

Rep: Reputation: 7946Reputation: 7946Reputation: 7946Reputation: 7946Reputation: 7946Reputation: 7946Reputation: 7946Reputation: 7946Reputation: 7946Reputation: 7946Reputation: 7946
Quote:
Originally Posted by hawk__0 View Post
Scratch that, I got it working... sort of. I need to now know how to chomp every OTHER line. Here is my current code:
Code:
#!/usr/bin/perl
use strict;
use warnings;

chomp(my $file = $ARGV[0]);
open (FILE, "$file") or die "Error: $!";
while(<FILE>){
print "Chomping " . $_ . "\n";
chomp $_;
}
close FILE;
Now it's not working WTH!? What does chomp remove? CR? LF? CR/LF?
Chomp removes any trailing input record separator. Could be a CR, CR/LF, etc., which can be defined to be whatever you want.
Read more here:
http://perldoc.perl.org/functions/chomp.html


The $. variable holds the current line number. So
Code:
while (<FILE>) {
    <do something here> $_ if 1 & $. ;
}
may do the trick. After you've opened the input file, use the $. variable to tell you how many lines have been read. This will print odd-numbered lines. Replace "if" with "unless" to print even lines. There's also:
Code:
while(<>)
if($i++%2){ print; }
Also, every time you use the input operator (<>), you read a new line. You can read it into a variable, but you're not doing that, so it goes directly into the special variable $_. You read a line in the while condition, and then clobber it by reading the next line from the file. I'd suggest against using the $_ to work with, but assigning the line(s) to variables, and splitting them out. The $_ is ok for very small things, but not much else. Too many chances to clobber something.
 
Old 02-04-2010, 01:27 PM   #6
hawk__0
Member
 
Registered: Nov 2008
Posts: 105

Original Poster
Rep: Reputation: 15
Thanks for the reply, I just realized my problem was that I wasn't outputting to anything (other than STDOUT). For some reason I thought it would overwrite the file with my changes :P. Well anyways, I have it outputting to a file now but something is totally borked with my method lol. This obviously doesn't work:

Code:
#!/usr/bin/perl
use strict;
use warnings;

chomp(my $file = $ARGV[0]);
open (FILE, "$file") or die "Error: $!";
while(<FILE>){
print "Chomping " . $_ . "\n" if 1 & $.;
chomp($_) if 1 & $.;
open NEWFILE, ">Desktop/abc.csv";
print NEWFILE $_;
}
print "Output Done!\n";
I can't figure out how to accomplish this. It's messed because since I'm opening the output file, open closes the previous one automatically, which my while loop is running on. Once I figure this out I can implement the changes you mentioned, I just need to figure out how to have 1 file open and reading, while writing to another at the same time....

Last edited by hawk__0; 02-04-2010 at 01:47 PM.
 
Old 02-04-2010, 01:50 PM   #7
TB0ne
LQ Guru
 
Registered: Jul 2003
Location: Birmingham, Alabama
Distribution: SuSE, RedHat, Slack,CentOS
Posts: 26,553

Rep: Reputation: 7946Reputation: 7946Reputation: 7946Reputation: 7946Reputation: 7946Reputation: 7946Reputation: 7946Reputation: 7946Reputation: 7946Reputation: 7946Reputation: 7946
Quote:
Originally Posted by hawk__0 View Post
Thanks for the reply, I just realized my problem was that I wasn't outputting to anything (other than STDOUT). For some reason I thought it would overwrite the file with my changes :P. Well anyways, I have it outputting to a file now but something is totally borked with my method lol. This obviously doesn't work:

Code:
#!/usr/bin/perl
use strict;
use warnings;

chomp(my $file = $ARGV[0]);
open (FILE, "$file") or die "Error: $!";
while(<FILE>){
print "Chomping " . $_ . "\n" if 1 & $.;
chomp($_) if 1 & $.;
open NEWFILE, ">Desktop/abc.csv";
print NEWFILE $_;
}
print "Output Done!\n";
I can't figure out how to accomplish this. It's messed because since I'm opening the output file, open closes the previous one automatically, which my while loop is running on. Once I figure this out I can implement the changes you mentioned, I just need to figure out how to have 1 file open and reading, while writing to another at the same time....
Open your files at the top, before the loop. Like this:
Code:
#!/usr/bin/perl
use strict;
use warnings;

open (FILE, "$file") or die "Error: $!";
open NEWFILE, ">Desktop/abc.csv";

chomp(my $file = $ARGV[0]);

while(<FILE>){
  print "Chomping " . $_ . "\n" if 1 & $.;
  chomp($_) if 1 & $.;
  print NEWFILE $_;
  }

print "Output Done!\n";
 
Old 02-04-2010, 02:22 PM   #8
hawk__0
Member
 
Registered: Nov 2008
Posts: 105

Original Poster
Rep: Reputation: 15
Thanks a lot for the help, I almost have it sorted out. This is now my current code:

Code:
#!/usr/bin/perl
use strict;
use warnings;

chomp(my $file = $ARGV[0]);
open (FILE, "$file") or die "Error: $!";
open NEWFILE, ">Desktop/abc.csv" or die "Error: $!";
while(<FILE>){
chomp($_) if 1 & $.;
print NEWFILE $_;
}
print "\nOutput Done!\n";
It works, except doesn't seem to be chomping anything. It's just duplicating the existing file... instead of chomping every 2nd line (starting at line 1)
 
Old 02-04-2010, 02:32 PM   #9
Sergei Steshenko
Senior Member
 
Registered: May 2005
Posts: 4,481

Rep: Reputation: 454Reputation: 454Reputation: 454Reputation: 454Reputation: 454
Quote:
Originally Posted by hawk__0 View Post
Thanks a lot for the help, I almost have it sorted out. This is now my current code:

Code:
#!/usr/bin/perl
use strict;
use warnings;

chomp(my $file = $ARGV[0]);
open (FILE, "$file") or die "Error: $!";
open NEWFILE, ">Desktop/abc.csv" or die "Error: $!";
while(<FILE>){
chomp($_) if 1 & $.;
print NEWFILE $_;
}
print "\nOutput Done!\n";
It works, except doesn't seem to be chomping anything. It's just duplicating the existing file... instead of chomping every 2nd line (starting at line 1)
And what is

Code:
if 1 & $.
supposed to mean ? Someone wants to show knowledge in the way numbers are represented internally ? If yes, does this task require this knowledge ? Does this knowledge help ? Dose such writing make code more readable ?

Also, why does one think $. variable is appropriate here ? I strongly suggest to read the part of

perldoc perlvar

related to $. variable.
 
Old 02-04-2010, 03:56 PM   #10
hawk__0
Member
 
Registered: Nov 2008
Posts: 105

Original Poster
Rep: Reputation: 15
You said:

Quote:
The $. variable holds the current line number. So
Code:
while (<FILE>) {
<do something here> $_ if 1 & $. ;
}
So I want to chomp line 1, so line 1 and 2 join. next, there will be a new line 2 because 1 and the old line 2 should be joined... right? Perhaps I'm being confusing.. I jsut want to turn this:

1
2
3
4

into this:
12
34
 
Old 02-04-2010, 04:08 PM   #11
Sergei Steshenko
Senior Member
 
Registered: May 2005
Posts: 4,481

Rep: Reputation: 454Reputation: 454Reputation: 454Reputation: 454Reputation: 454
Quote:
Originally Posted by hawk__0 View Post
You said:



So I want to chomp line 1, so line 1 and 2 join. next, there will be a new line 2 because 1 and the old line 2 should be joined... right? Perhaps I'm being confusing.. I jsut want to turn this:

1
2
3
4

into this:
12
34

Who "you" ? Have you read

perldoc perlvar

?

The document uses different wording and has a number of suggestions/alternatives.
 
Old 02-04-2010, 04:38 PM   #12
hawk__0
Member
 
Registered: Nov 2008
Posts: 105

Original Poster
Rep: Reputation: 15
Woops, it didn't show for some reason. Anyways I've found a solution to my problem:
Code:
#!/usr/bin/perl
use strict;
use warnings;

chomp(my $file = $ARGV[0]);
open (FILE, "$file") or die "Error: $!";
open NEWFILE, ">Desktop/abc.csv" or die "Error: $!";
my $x = 0;
while(<FILE>){
if ($x eq 0){
	chomp($_);
	print NEWFILE $_;
	$x = 1;
}
else{
	print NEWFILE $_;
	$x = 0;
}
}
print "\nOutput Done!\n";
 
Old 02-04-2010, 04:41 PM   #13
Sergei Steshenko
Senior Member
 
Registered: May 2005
Posts: 4,481

Rep: Reputation: 454Reputation: 454Reputation: 454Reputation: 454Reputation: 454
Quote:
Originally Posted by hawk__0 View Post
Woops, it didn't show for some reason. Anyways I've found a solution to my problem:
Code:
#!/usr/bin/perl
use strict;
use warnings;

chomp(my $file = $ARGV[0]);
open (FILE, "$file") or die "Error: $!";
open NEWFILE, ">Desktop/abc.csv" or die "Error: $!";
my $x = 0;
while(<FILE>){
if ($x eq 0){
	chomp($_);
	print NEWFILE $_;
	$x = 1;
}
else{
	print NEWFILE $_;
	$x = 0;
}
}
print "\nOutput Done!\n";
You solution can be further simplified:

Code:
my $x = 1;
while(<FILE>)
  {
  chomp if $x;
  $x = 1 - $x;

  print NEWFILE $_;
  }

Last edited by Sergei Steshenko; 02-04-2010 at 04:43 PM.
 
Old 02-04-2010, 07:44 PM   #14
ghostdog74
Senior Member
 
Registered: Aug 2006
Posts: 2,697
Blog Entries: 5

Rep: Reputation: 244Reputation: 244Reputation: 244
Quote:
Originally Posted by hawk__0 View Post
You said:



So I want to chomp line 1, so line 1 and 2 join. next, there will be a new line 2 because 1 and the old line 2 should be joined... right? Perhaps I'm being confusing.. I jsut want to turn this:

1
2
3
4

into this:
12
34
Code:
while (<>) {
    chomp;      
    printf (($. % 2 == 0) ? $_ . "\n" : $_ . '');
}
 
Old 02-04-2010, 08:01 PM   #15
Sergei Steshenko
Senior Member
 
Registered: May 2005
Posts: 4,481

Rep: Reputation: 454Reputation: 454Reputation: 454Reputation: 454Reputation: 454
Quote:
Originally Posted by ghostdog74 View Post
Code:
while (<>) {
    chomp;      
    printf (($. % 2 == 0) ? $_ . "\n" : $_ . '');
}
Well, with this approach '$_ . "\n"' looks as compensation for overreaction, and the code can be rewritten without the overreaction -> compensation:

Code:
while(<$ifh>)
  {
  print $ofh ($ifh->input_line_number() % 2) ? do{chomp; $_} : $_;
  }
- 'do' statement returns the last expression - very convenient, I'm using this feature pretty frequently.

Using $. is very unsafe, one better forgets about this variable. Unsafe in a sense of getting confused.

...

One needs to check whether line numbering begins from 1 or 0, I think from 1.

Last edited by Sergei Steshenko; 02-04-2010 at 08:03 PM.
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
Perl: Match part of a line and replace with another line from the same file briana.paige Linux - Newbie 8 06-27-2009 06:35 AM
Perl question: delete line from text file with duplicate match at beginning of line mrealty Programming 7 04-01-2009 06:46 PM
grab the line below a blank line and the line above the next blank line awk or perl? Pantomime Linux - General 7 06-26-2008 08:13 AM
str.chomp! masternerdguy Programming 3 07-17-2007 02:39 PM
Perl add numbers in 2nd field twantrd Programming 6 10-19-2006 08:26 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 05:09 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration