By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
455,847 Members | 1,336 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 455,847 IT Pros & Developers. It's quick & easy.

Read Character by Character in each line

P: 50
I'm trying to read each line, character by character, to determine if a line has a semicolon in it. I'm trying to count the number of lines that have a semicolon. In all of the files in one directory.

I have 2 problems, one problem is it displays '.' and '..' and the subdirectory as files which I want it to avoid. I tried to use grep but I was unsuccessful. The second problem I'm having is that while it will read the amount of lines I have, I want it to only count the lines that have a semicolon in it. My approach to this problem was to read each line character by character and compare it to semicolon, if it matched than the line_count would increment by 1 otherwise goto next line.

Expand|Select|Wrap|Line Numbers
  1.  
  2. #!/bin/perl
  3.  
  4. use strict;
  5. #use warnings;
  6.  
  7. use File::Copy;
  8.  
  9. my $line_count = 0;
  10. my $dir_name = "C:\\Example\\";
  11.  
  12. opendir DIR, $dir_name or die "Error opening dir\n";
  13.  
  14. #for each file in the directory, display the name and count the number of lines
  15. foreach my $file (readdir DIR)
  16. {
  17.     print "File in $dir_name is $file \n";
  18.  
  19.     #need to put dir_name and file next to each other because
  20.     #they are both strings which combined together locate the file.
  21.     open (MYFILE, "$dir_name$file");
  22.     #while we haven't gotten to the EOF, count the lines
  23.     while (<MYFILE>) 
  24.     {
  25.         #my @lines = <MYFILE>;
  26.  
  27.         chomp;
  28.         #if(@lines eq ';')
  29.         #{
  30.             $line_count++;
  31.         #}
  32.  
  33.         print "$line_count";
  34.         print "$_\n";
  35.     }
  36.     close (MYFILE);
  37.  
  38.     print "There are $line_count lines in $file\n\n";
  39.  
  40.     $line_count = 0;
  41. }
  42.  
  43. closedir DIR;
  44.  
  45.  
In the meantime, I will continue to figure this out, if I do I will post the solution.
Thanks in advance for any help.
Mar 19 '08 #1
Share this Question
Share on Google+
6 Replies


P: 2
d41
'.' and '..' are two folders (I think) in every directory. '.' leads into the current directory, and '..' leads into the parent directory. If you're reading all the files in a foreach loop, you could just tell it next; if the filename is '.' or '..'. Or you could have it skip all filenames that start with a dot '.'.

For checking if a line has a semicolon, you can just use a regular expression or the index() function
regular expression: /;/ (Don't use a regular expression for something this simple, though)
or the index function: index($line,";"); will return the place it found a semicolon, or -1 if it didn't find a semicolon.
Mar 19 '08 #2

numberwhun
Expert Mod 2.5K+
P: 3,503
I would actually go a different direction with this. Taking into account that you want to not have the "." and "..", you would need to figure out how to do an "ls" of whatever directory it is and then scan each line (I would personally use a regular expression) for the semi colon.

Here is some code I put together a little while ago that does an "ls -rt" of a directory, only using strictly perl, no system() function.

Expand|Select|Wrap|Line Numbers
  1. ### Declarations ###
  2. my @filesarray;
  3. my $directory;
  4.  
  5. ### Test to ensure that there is only one directory supplied on the command line
  6. if($#ARGV != "0")
  7. {
  8.    print("This script requires you to supply one and only one direcotry path.\n");
  9.    print("Please re-execute this script with a directory path.\n");
  10.    print("Usage:  lsrt.pl <directory_path>\n");
  11.    exit();
  12. }
  13.  
  14. ### Take the argument supplied on the command line and put it into a variable
  15. $directory = shift @ARGV;
  16.  
  17. ### Change directories to the directory specified as an option to this script
  18. chdir($directory);
  19.  
  20. ### Take the files in the current directory (obtained through the glob <*>)
  21. ### and compare them, sorting them into the array by the oldest first.
  22. ### The variables $a and $b are used specifically by sort and if you
  23. ### reverse them here, you will get the sort in the reverse order with the
  24. ### newest as the first element of the array.
  25. @filesarray = sort{ -M $b <=> -M $a } <*>;
  26.  
  27. ### Print out the array, one element per line.
  28. foreach(@filesarray)
  29. {
  30.     print("$_\n");
  31. }
  32.  
There should be plenty of comments there to enable you to understand it.

After you incorporate the bit that does the listing into your script, you will then have to examine each line (again, regex for that) for the ";".

But that is just another idea of what you can do. How you do it is up to you, I just wanted to share. (TIMTOWTDI)

Regards,

Jeff
Mar 19 '08 #3

P: 50
Thanks a lot guys, I'm going to try both approaches to see what happens. d41 thanks for the filename comparison idea and your approach to checking semicolons. numberwhun your code makes it easier to see the bigger picture.
Mar 19 '08 #4

KevinADC
Expert 2.5K+
P: 4,059
I would avoid doing this as a general rule:

Expand|Select|Wrap|Line Numbers
  1. @filesarray = sort{ -M $b <=> -M $a } <*>;
sorting files that way is slow and in this case there appears to be no reason to sort the files at all. The better way if you did have to sort the files would be to get all the -M values first then sort them. That way you never have to stat the same file more than once.
Mar 19 '08 #5

P: 50
Ok thanks to your help guys, I found the solution. Here it is:

Expand|Select|Wrap|Line Numbers
  1.  
  2. #!/bin/perl
  3.  
  4. use strict;
  5. #use warnings;
  6.  
  7. my $line_count = 0;
  8. my $dir_name = "C:\\Example\\";
  9.  
  10. opendir DIR, $dir_name or die "Error opening dir\n";
  11.  
  12. #for each file in the directory, display the name and count the number of lines
  13. foreach my $file (readdir DIR)
  14. {
  15.     #every directory has '.' and '..' as folders, skip over them
  16.     if($file eq '.')
  17.     {
  18.         next;
  19.     }
  20.     elsif($file eq '..')
  21.     {
  22.         next;
  23.     }
  24.  
  25.     print "File in $dir_name is $file \n";
  26.  
  27.     #need to put dir_name and file next to each other because
  28.     #they are both strings which combined together locate the file.
  29.     open (MYFILE, "$dir_name$file");
  30.     #while we haven't gotten to the EOF, count the lines
  31.     while (<MYFILE>) 
  32.     {
  33.         chomp;
  34.  
  35.         my $result = index($_, ";");
  36.  
  37.         if($result != -1)
  38.         {
  39.             $line_count++;
  40.         }    
  41.  
  42.         #print "\nresult: $result\n"
  43.         print "$line_count";
  44.         print "$_\n";
  45.  
  46.     }
  47.     close (MYFILE);
  48.  
  49.     print "There are $line_count lines in $file\n\n";
  50.  
  51.     $line_count = 0;
  52. }
  53.  
  54. closedir DIR;
  55.  
  56.  
Mar 19 '08 #6

KevinADC
Expert 2.5K+
P: 4,059
Nothing wrong with your code, this is just less verbose:

Expand|Select|Wrap|Line Numbers
  1. #!/bin/perl
  2.  
  3. use strict;
  4. use warnings;
  5. my $dir_name = "C:\\Example\\";
  6. opendir DIR, $dir_name or die "Error opening dir: $!\n";
  7. readdir DIR; #skip '.'
  8. readdir DIR; #skip '..'
  9.  
  10. while (my $file = readdir DIR){
  11.    my $line_count = 0;
  12.    print "File in $dir_name is $file \n";
  13.    open (MYFILE, "$dir_name$file") or print "Could not open $file: $!\n";
  14.    #while we haven't gotten to the EOF, count the lines
  15.    while (<MYFILE>){
  16.       chomp;
  17.       $line_count++ if ( index($_, ';') > -1);
  18.       print "$line_count\n";
  19.    }
  20.    close (MYFILE);
  21.    print "There are $line_count lines in $file\n\n";
  22. }
  23. closedir DIR;
Mar 19 '08 #7

Post your reply

Sign in to post your reply or Sign up for a free account.