2017-01-28 1 views
0

Уже опубликовано решение проблемы с использованием awk или sed вполне стандартно и помогает в случае, если что-то не работает правильно.Чистый скрипт Bash Cuting, который не обеспечивает эффективную работу

как для:

StringStr="ValueA:ValueB,ValueC:ValueC" ; 

echo ${StringStr} | gawk -F',' 'BEGIN{}{for(intx=1;intx<=NF;intx++){printf("%s\n",$(intx))}}END{}' 

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

Для эффективной причине я разработать свою собственную библиотеку Баш функции на github.com и падают на технику, которые не работают, как предполагается, и здесь рабочий пример:

Этот метод используют баш «соответствия шаблону Удалить префикс 'и' Удалить шаблон суффикса '. Цель состоит в том, чтобы получить цепочку цепочечной информации, чтобы использовать как можно более простой элемент bash-shell для извлечения вставленного элемента.

По настоящее у меня есть первое заявление, чтобы получить строку из определенного формата: Ex:

StringPattern="__VALUE1__:__VALUE2__," 

Формат предполагают, добавление в цепи, многие шаблон типа StringPattern. Остальные ',' будут использоваться для разделения и отделения строки в VALUE1: VALUE2 Форма.

как StringStorage будет держать много раз, разобрано StringPattern, здесь 2 примера: 1 - образец 1

StringPattern="VariableA:InformationA," 
StringStorage="${StringStorage}${StringPattern}" ; 

2 - образец 2

StringPattern="VariableB:InformationB," 
StringStorage="${StringStorage}${StringPattern}" ; 

В этот момент StringStorage правильно держать эту информацию :

StringStorage="VariableA:InformationA,VariableB:InformationB," 

Теперь с StringStorage, базовый ч алгоритм сделан из смеси «Удалить соответствие префиксов шаблона» и «Удалить соответствующий суффикс шаблон» делает работу для этого случая:

### Description of IntCsvCount 
### does remove all chosed Comma Separated value ',' from StringStorage 
### and subtract from the original length the removed result from this 
### subtraction. This produce IntCsvCount == 2 
IntCsvCount=$(cstr=${StringStorage//,/} ; echo $((${#StringStorage} - ${#cstr}))) ; 

### Description of 
### Will be re Variable used to put the Extracted sequence. 
bstr="" ; 

### Description of for 
### Received information from IntCsvCount it should count 
### from 0 to Last element . This case it's ${IntCsvCount}-1 or 1 in 
### my example. 

for ((intx=0 ; intx <= ${IntCsvCount}-1 ; intx++)) ; do 
    ### This extracting First Segment based on 
    ### Remove matching suffix pattern ${parameter%word} where 
    ### work is ${astr#*,} (Remove matching prefix pattern) of 
    ### everything in $astr until find a ',' . 
    bstr=${astr%*${astr#*,}} ; 
    ### Destroying the $bstr part in by starting the astr to position of 
    ### the end of size equivalent of bstr size (${#bstr}), end position is 
    ### equal to [ Highest-String size ] - [ Shortest-String size ] 
    astr=${astr:${#bstr}:$((${#astr} - ${#bstr}))} ; 
    echo -ne "Element: ${bstr}\n" ; 
done 

Это должно произвести следующий ответ.

Element: VariableA:InformationA, 
Element: VariableB:InformationB, 

Подставляя это в функцию потребуется только изменить CSV на «:» и пусть извлечь «VariableA» и «InformationA».

Проблема начинается с использования String с неравномерной. Как видно на этой доске, пример предложения и сокращение части должен работать на неравномерной строке, но здесь образец, который не работает.И у меня есть более чем один посоветует в руке с помощью Gawk, СЭД, даже вырезать, но из этого алгоритма он не работает с этим образцом:

astr="master|ZenityShellEval|Variable declaration|Added Zenity font support to allow choosing both font-name and size and parsing the zenition option, notice --font option require a space between font and size.|20170127|" 

пришедшего из

astr=$(zenity --width=640 --height=600 --forms --show-header --text="Commit Message" --add-entry="Branch name" --add-entry="function" --add-entry="section" --add-entry="commit Message" --add-calendar="Commit Date" --forms-date-format="%Y%m%d" --separator='|') ; 

Я также исполнившим выход должен выглядеть так, как выглядит StringPattern: astr = "$ {astr} |" ;

Тот же код, кроме CSV (Comma Separated Value), был изменен с ',' на '|'

IntCsvCount=$(cstr=${astr//|/} ; echo $((${#astr} - ${#cstr}))) ; 
bstr="" ; 
for ((intx=0 ; intx <= ${IntCsvCount}-1 ; intx++)) ; do 
    bstr=${astr%*${astr#*|}} ; 
    astr=${astr:${#bstr}:$((${#astr} - ${#bstr}))} ; 
    echo -ne "Element: ${bstr}\n" ; 
done 

Где на этот раз выход генерирует следующий вывод:

Element:master|ZenityShellEval|Variable declaration|Added Zenity font support to allow choosing both font-name and size and parsing the zenition option, notice --font option require a space between font and size.|20170127| 
Element: 
Element: 
Element: 

Есть ли какая-то причина, почему он не должен работать каждый раз?

+3

Это довольно сложно. Можете ли вы упростить его до ввода, фактического и ожидаемого вывода и какого кода вы пытались получить этот результат. – 123

ответ

0

Итак, вы писали этот сценарий AWK:

BEGIN{}{for(intx=1;intx<=NF;intx++){printf("%s\n",$(intx))}}END{} 

Если я правильно понимаю, вы говорите, что это именно то, что вы хотите, и единственная проблема заключается в том, что вы не хотите, чтобы полагаться на AWK?

В этом случае вы действительно делаете это более сложным, чем вам нужно. Вы можете использовать функции подстроки заместительную Bash непосредственно:

str=ValueA:ValueB,ValueC:ValueC 
printf '%s\n' "${str//,/$'\n'}" 
+0

Скрипт awk был альтернативой, по моим сведениям, для учета трафика с iptable для веб-провайдера. Но, как уже упоминалось, это была только альтернатива, и на самом деле это должно было оставить рабочее решение менее чем в 2 строках: 'bstr = $ {astr% * $ {astr # * |}}; astr = $ {astr: $ {# bstr}: $ (($ {# astr} - $ {# bstr}))}; '. Это решение может вывести CSV в самый правый элемент сразу, пока строка внутри astr не станет пустой.Он эффективен и требует меньше циклов процессора за итерацию. Я должен опубликовать что-то внутри моего github Fnct.D. Это попытка быстро развиваться и быть ясным. –

0

Если я понять конец вашего вопроса правильно, у вас есть строка, как astr="master|ZenityShellEval|Variable declaration|Added Zenity font support to allow choosing both font-name and size and parsing the zenition option, notice --font option require a space between font and size.|20170127|" , и вы хотите следующий вывод:

Element: master 
Element: ZenityShellEval 
Element: Variable declaration 
Element: Added Zenity font support to allow choosing both font-name and size and parsing the zenition option, notice --font option require a space between font and size. 
Element: 20170127 

Самый простой способ я мог подумать об этом:

s="${astr%|}"; echo "Element: ${s//|/$'\n'Element: }"; 

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

(IFS='|'; declare -a a=(${astr}); printf "Element: %s\n" "${a[@]}") 

Bash Hackers Wiki has a great page on arrays, который я рекомендую просмотреть.

+0

2 наиболее важные вещи для сохранения 'bstr = $ {astr% * $ {astr # * |}}; astr = $ {astr: $ {# bstr}: $ (($ {# astr} - $ {# bstr}))}; ', наконец-то работал, я думаю, что это что-то с памятью, и как только проблемы решены, он отработал так что либо без вопросов, но и с использованием метода для эффективного извлечения самого левого CSV с меньшим количеством деклараций и меньшим количеством работы. С массивом мне нравится использовать 'declare -a Array = ($ {astr // | /});' Он расширяет CSV по пространству и Array, чтобы разбить его на элементы. Требовать добавить элемент 'for в $ {Array [@]}; do echo $ {item}; done ', где мы неэффективны для добавления 3 строк. –

0

Здесь же работают на последних нескольких темах:

IFS="|" read -ra arr<<<"${astr}" 
printf "Element: %s\n" "${arr[@]}" 

Я думал, что я хотел бы добавить, что ваш оригинальный AWK немного раздутый на:

echo -n "ValueA:ValueB,ValueC:ValueC" | awk '1' RS="," 

И конечно, AWK для текущее решение:

awk 'NF && $0 = "Element: " $0' RS="|" <<<"$astr" 
Смежные вопросы