0

I'm a bit stuck into an issue on how to declare a grep from within a perl script. What I want to do is let my perl script to execute the following command:

cat config.ini | grep -v "^#" | grep -v "^$"

Normally this expression will clean up / filter all the entries who have # and $ at the beginning and print the variables configured.

However I don't know how to declare it. I have used next expression, but when i get to the point to introduce grep # or $ it fails

system("(cat config.ini| grep ........);

Any suggestion?

1
  • 1
    /^[#$]/ or print while <$fh>; or perl -ne '/^[#$]/ or print' config.ini Commented Jun 30, 2015 at 12:41

3 Answers 3

4
cat config.ini | grep -v "^#" | grep -v "^$"

is a poor way of writing

grep -v "^[#$]" config.ini

To produce the string

grep -v "^[#$]" config.ini

You can use the string literal

'grep -v "^[#$]" config.ini'

So

system('grep -v "^[#$]" config.ini');
die("Killed by signal ".($? & 0x7F)."\n") if $? & 0x7F;
die("Exited with error ".($? >> 8)."\n") if $? >> 8;

system('grep -v "^[#$]" config.ini');

is short for

system('/bin/sh', '-c', 'grep -v "^[#$]" config.ini');

But we don't need the shell, so the following can use instead:

system('grep', '-v', '^[#$]', 'config.ini');
die("Killed by signal ".($? & 0x7F)."\n") if $? & 0x7F;
die("Exited with error ".($? >> 8)."\n") if $? >> 8;

But it would be cleaner and more robust to do it in Perl.

open(my $fh, '<', 'config.ini')
   or die($!);

while (<$fh>) {
   print if !/^[#$]/;
}
Sign up to request clarification or add additional context in comments.

Comments

3

If you're making external calls to grep from inside a Perl program, then you're doing it wrong. There's nothing that grep can do that Perl can't do for you.

while (<$input_filehandle>) {
  next if /^[#$]/; # Skip comment lines or empty lines.

  # Do something with your data, which is in $_
}

Update: Thinking further about this, I think I'd write it slightly differently.

while (<$input_filehandle>) {
  # Split on comment character - this allows comments to start
  # anywhere on the line.
  my ($line, $comment) = split /#/, $_, 2;

  # Check for non-whitespace characters in the remaining input.
  next unless $line =~ /\S/;

  # Do something with your data, which is in $_
}

Comments

0
print if !(/^#/|/^$/);

I did try using the expression suggested but didn't work as good as this one, is there a way to reduce it or write ir in a better way?

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.