Search code examples
tcsh

How to perform arithmetic operations on the output of a shell command


I'm trying to count the number of entries in a set of log files. Some of these logs have lines that should not be counted (the number of these remains constant). The way I'd like to go about this is a Perl script that iterates over a hash, which maps log names to a one-liner that gets the number of entries for that particular log (I figured this would be easier to maintain than dozens of if-else statements)

Getting the number of lines is simple:

wc -l [logfile] | cut -f1 -d " "

The issue is when I need to subtract, say, 1 or 2 from this value. I tried the following:

expr( wc -l [logfile] | cut -f1 -d " " ) - 1

But this results in an error:

Badly placed ()'s.

: Command not found.

How do I perform arithmetic operations on the output of a shell command? Is there a better way to do this?


Solution

  • It's a bit clunky to shell out to wc and cut just to count the number of lines in a file.

    Your requirement isn't very clear, but this Perl code creates a hash that relates every log file in the current directory to the number of lines it contains. It works by reading each file into an array of lines, and then evaluating that array in scalar context to give the line count. I hope it's obvious how to subtract a constant delta from each line count.

    use strict;
    use warnings;
    
    my %lines;
    
    for my $logfile ( glob '*.log' ) {
    
        my $num_lines = do {
            open my $fh, '<', $logfile or die qq{Unable to open "$logfile" for input: $!};
            my @lines = <$fh>;
        };
    
        $lines{$logfile} = $num_lines;
    }
    

    Update

    After a comment from w.k, I think this version may be rather nicer

    use strict;
    use warnings;
    
    my %lines;
    
    for my $logfile ( glob '*.log' ) {
        open my $fh, '<', $logfile or die qq{Unable to open "$logfile" for input: $!};
        1 while <$fh>;
        $lines{$logfile} = $.;
    }