Извлечение частично повторяющихся узоров в строках текстового файла - PullRequest
0 голосов
/ 09 ноября 2018

Дан текстовый файл вида:

firstword<number1>,<string1>:<number2>,<string2>:<number3>,<string>:<number4>...
firstword<number1>,<string1>:<number2>,<string2>:<number3>,<string>:<number4>...
firstword<number1>,<string1>:<number2>,<string2>:<number3>,<string>:<number4>...
...

где каждая строка может отличаться друг от друга и может содержать любое количество пар строка: число. «первое слово» всегда одинаково. Содержимое строк и чисел может меняться, например, числа могут быть «12345», строка может быть «abc» (без кавычек).

Кроме того, строка может иметь несколько раз одну и ту же строку (сколько раз она неизвестна и различна для каждой строки), каждая из которых имеет свой связанный номер. Например:

firstword123,abc:123,cde:234,abc:345,def:456

Если теперь нужно извлечь только первое слово и число (в данном случае firstword123), а также все пары строка: число в строке для конкретной строки, как это можно сделать? В приведенном выше примере, если для строки выбирается значение «abc», извлеченная строка должна выглядеть следующим образом:

firstword123,abc:123,abc:345

Я ищу решение, которое работает с Bash (и, возможно, с другими командами).

Ответы [ 2 ]

0 голосов
/ 10 ноября 2018

вы можете использовать Perl для этого

#!/usr/bin/perl
my $first='firstword123';
my $str='abc';

while (<DATA>) {
    next if not /^$first/;
    print "$first";
    print ",$_" for ($_ =~ /$str:\d+/g);
}

__DATA__
firstword123,abc:123,cde:234,abc:345,def:456

из:

firstword123,abc:123,abc:345
0 голосов
/ 09 ноября 2018

Не однострочник, а решение для всех задач.Если вам нужен более быстрый код, мы можем написать что-нибудь в awk или perl ...

$: cat keyscan
#! /bin/env bash

key="$1"
while read line
do start=${line//,*/}
   line=${line#$start}
   line=${line#,}
   while [[ -n "$line" ]]
   do case "$line" in
      $key:[0-9]*) lead="${line//,*/}"
                   start="$start,$lead"
                   line="${line#$lead}"
                   line="${line#,}"  ;;
              *,*) line="${line#*,}" ;;
                *) line='' ;;
      esac
   done
   printf "$start\n"
done

$: cat data
firstword123,abc:123,cde:234,abc:345,def:456

$: ./keyscan abc < data
firstword123,abc:123,abc:345

$: ./keyscan def < data
firstword123,def:456

$: ./keyscan cde < data
firstword123,cde:234

Это не будет быстрым, потому что в каждой строке ввода есть цикл обработки, но он работает наобразец строки данных, которые вы дали.

...