开发者

Perl / grep / awk -- splitting multiple results, if statement checking for second string

I am trying to grep a file for the first 2 matches of a string (there will only ever be a maximum 2 matches) including some context (grep -B 1 -A 5), split each set of 7 lines into two separate variables and write an if statement based on whether or not each set contains a different string.

In some cases, the file may contain only one match.

开发者_C百科

I know how to grep for the two matches, but not how to split them into separate variables. I can also write an if statement to check if the variable is empty (indicating a lack of a second match). I am not sure how to check each variable to see if it contains the second string. Any assistance would be helpful. Thanks!

Example:

grep -B1 -A5 "Resolution:" file.txt

Color LCD:
  Resolution: 1440 x 900
  Pixel Depth: 32-Bit Color (ARGB8888)
  Main Display: Yes
  Mirror: Off
  Online: Yes
  Built-In: Yes
LED Cinema Display:
  Resolution: 1920 x 1200
  Depth: 32-Bit Color
  Core Image: Hardware Accelerated
  Mirror: Off
  Online: Yes
  Quartz Extreme: Supported

Desired result based on whether or not each match set contains "Main Display":

$mainDisplay = Color LCD

$secondDisplay = LED Cinema Display (or null indicating no second match)


Your file is valid YAML, so if you have installed YAML perl module, here is an oneliner:

eval $(perl -MYAML -0777 -e '$r=Load(<>);map { exists($r->{$_}->{"Main Display"}) ? print "main=\"$_\";\n" : print "second=\"$_\";\n" } keys %$r' < filename.txt)
echo =$main= =$second=

so, after the eval, here are shell variables main and second

or, exactly for your OS X, with system_profiler command:

eval $(
    system_profiler SPDisplaysDataType |\
    grep -B1 -A5 'Resolution:' |\
    perl -MYAML -0777 -e '$r=Load(<>);map { printf "%s=\"%s\"\n", exists($r->{$_}->{"Main Display"}) ? "main" : "second", $_ } keys %$r'
)
echo =$main=$second=


my($first, $second) = split /--\n/, qx/grep -B1 -A5 foo data.text/;


awk:

awk -F : '
    /^[^[:space:]]/ {current = $1; devices[$1]++}
    $1 ~ /Main Display/ {main = current}
    END {
        for (d in devices)
            if (d == main)
                print "mainDisplay=\"" d "\""
            else
                print "secondDisplay=\"" d "\""
    }
'

outputs

mainDisplay="Color LCD"
secondDisplay="LED Cinema Display"

which you can capture and eval in the shell.


Here's a perl solution. Use it like so: script.pl Resolution:. Default search is "Resolution:".

The values are stored in %values, for example:

$values{Color LCD}{Resolution} == "1440 x 900";

use strict;
use warnings;

my $grep = shift || "Resolution:";

my %values;
my $pre;
while (my $line = <DATA>) {
    chomp $line;
    if ($line =~ /$grep/) {
        my @data;
        push @data, scalar <DATA> for (0 .. 4);
        chomp @data;
        for my $pair ($line, @data) {
            if ($pair =~ /^([^:]+): (.*)$/) {
                $values{$pre}{$1} = $2;
            } else { die "Unexpected data: $pair" }
        }
    } else {
        $pre = $line;
    }
}

use Data::Dumper;

print Dumper \%values;

__DATA__
Color LCD:
  Resolution: 1440 x 900
  Pixel Depth: 32-Bit Color (ARGB8888)
  Main Display: Yes
  Mirror: Off
  Online: Yes
  Built-In: Yes
LED Cinema Display:
  Resolution: 1920 x 1200
  Depth: 32-Bit Color
  Core Image: Hardware Accelerated
  Mirror: Off
  Online: Yes
  Quartz Extreme: Supported
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜