Perl / grep / awk - разделение нескольких результатов, если оператор проверяет вторую строку - PullRequest
1 голос
/ 03 июня 2011

Я пытаюсь выполнить поиск файла для первых двух совпадений строки (максимум совпадений будет только 2), включая некоторый контекст (grep -B 1 -A 5), разбить каждый набор из 7 строк на дваразделите переменные и напишите оператор if, основываясь на том, содержит ли каждый набор свою строку.

В некоторых случаях файл может содержать только одно совпадение.

Я знаю, как выполнить поиск grep длядва совпадения, но не как разбить их на отдельные переменные.Я также могу написать оператор if, чтобы проверить, является ли переменная пустой (что указывает на отсутствие второго совпадения).Я не уверен, как проверить каждую переменную, чтобы увидеть, если она содержит вторую строку.Любая помощь будет полезна.Спасибо!

Пример:

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

Желаемый результат в зависимости от того, содержит ли каждый набор совпадений "MainДисплей ":

$ mainDisplay = Цветной ЖК-дисплей

$ secondDisplay = Светодиодный дисплей кинотеатра (или ноль, указывающий отсутствие второго совпадения)

Ответы [ 4 ]

1 голос
/ 03 июня 2011

Ваш файл является действительным YAML, поэтому, если вы установили модуль Perl YAML, вот один из символов:

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=

, поэтому после eval здесь находятся переменные оболочки main и second

или, точно для вашей OS X, с помощью команды system_profiler:

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=
0 голосов
/ 03 июня 2011

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 "\""
    }
'

выводит

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

, которые вы можете захватить и eval в оболочке.

0 голосов
/ 03 июня 2011

Вот решение Perl.Используйте это так: script.pl Resolution:.По умолчанию используется поиск «Resolution:».

Значения хранятся в %values, например:

$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 голосов
/ 03 июня 2011
my($first, $second) = split /--\n/, qx/grep -B1 -A5 foo data.text/;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...