bash разделить текст на ограниченные символьные сегменты (член массива) - PullRequest
0 голосов
/ 07 мая 2010

у меня есть текст, такой как

http://pastebin.com/H8zTbG54

мы можем сказать, что этот текст представляет собой набор правил, разделенных "ИЛИ" в конце строк

Мне нужно поместить набор строк (правил) в сегменты (члены массива bash), но у меня есть ограничение на число символов для каждого элемента массива, равное 1024

поэтому каждый член массива должен содержать набор правил, но количество символов для каждого члена массива не может превышать 1024

предположим, что текст правила похож на или ИЛИ ИЛИ ИЛИ ИЛИ ИЛИ ИЛИ ИЛИ ИЛИ ИЛИ * h

вывод должен быть член массива 1 = ИЛИ b

член массива 2 = c ИЛИ ИЛИ ИЛИ

член массива 3 = f ИЛИ g

член массива 4 = h

может кто-нибудь помочь мне сделать это

работает на сервере Solaris 10

Ответы [ 2 ]

1 голос
/ 07 мая 2010

Это не совсем тривиально и потребует немного большего разъяснения, но в основном вы сначала разделяете их по ИЛИ / И (и, возможно, некоторым другим шаблонам, в зависимости от ваших потребностей), а затем рекурсивно разделяете те куски, которые больше 1024 .

P.S. Это кажется одним из тех случаев, когда использование полноценного языка сценариев, такого как Perl, Python, PHP или любой другой, сможет достичь результата более удобно.

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

function splitByOr($input)
{
  $tokens = explode(" OR ",$input);
  foreach ($t in $tokens)
    if (strlen($t) > 1024)
         $t=splitByOr($t);
  return $tokens;
}
0 голосов
/ 07 мая 2010

Ни одно из отдельных правил в файле samplerule не превышает 148 символов в длину - намного меньше, чем ограничение в 1024 символа. Вы не говорите, что следует делать с правилами, если они превышают этот предел.

Это очень простой Bash-скрипт, который разбит ваш пример на литерале "\ n" на массив и называется "rules". Он пропускает строки длиной более 1024 символов и выводит сообщение об ошибке:

#!/bin/bash
while read -r line
do
    (( count++ ))
    if (( ${#line} > 1024 ))
    then
        echo "Line length limit of 1024 characters exceeded: Length: ${#line} Line no.: $count"
        echo "$line"
        continue
    fi
    rules+=($line)
done < <(echo -e "$(<samplerule)")

Эта вариация будет урезать длину строки без учета последствий:

#!/bin/bash
while read -r line
do
    rules+=(${line:0:1024})
done < <(echo -e "$(<samplerule)")

Если литерала "\ n" на самом деле нет в файле, и вам нужно использовать массивы Bash, а не кодировать его целиком в AWK, измените строку в любой из версий выше, которая гласит:

done < <(echo -e "$(<samplerule)")

сказать это:

done < <(awk 'BEGIN {RS="OR"} {print $0,"OR"}' samplerule)
if [[ "${rules[${#rules[@]}-1]}" == "OR" ]]
then
    unset "rules[${#rules[@]}-1]"
fi

, который разделит строки на "ИЛИ".

Редактировать: Добавлена ​​команда для удаления лишнего "ИЛИ" в конце.

...