2014-09-21 5 views
0

У меня есть потенциальные входы, которые будут поступать из команды read -e -p в сценарии bash. Например, пользователь будет вводить L50CA. Некоторые другие возможности, которые пользователь может ввести, заключаются в следующем: K117CB, K46CE2, или V9CE1.Regex Matching for Bash

мне нужно разбить прочитанного в Я читал в так:.

read -e -p "What first atom? " sel1 

, то я хотел бы сделать массив как это (но это не будет отделяться):

arr1=($sel1) 

Но мне нужно, чтобы отделить массив, так что

${arr1[0]} равна L ${arr1[1]} равна 50 и ${arr1[2]} равен CA

Это разделение должно работать с другими возможными форматами ввода пользователя, такими как перечисленные выше. Кажется, Regex это способ сделать это. Я могу выделить первые два совпадения ввода со следующими регулярными выражениями: ^\D и \d*(?=\w)

Мне нужна помощь, соответствующая третьему компоненту и реализующая его в массив. В качестве альтернативы, это нормально, чтобы разбить пользовательский ввод на три новые переменные. Или мы можем разместить пробел между каждым из совпадений, так что L50CA преобразуется в L 50 CA, потому что тогда arr1=($sel1) будет работать.

Благодарим за помощь.

+0

Что расщепляется 'K46CE2'? 'K',' 46', 'CE2'? Или 'K',' 46', 'CE',' 2'? –

+0

Он разделился бы на K 46 CE2. Это нормально, если они выходят отдельно, как они это делали с ответом jm66, потому что тривиально просто объединить 3-ю и 4-ю позицию. – PhysicalChemist

ответ

1

В

for sel in L50CA K117CB K46CE2 V9CE1 
do 
     arr=($(sed 's/\([0-9][0-9]*\)/ \1 /g'<<<"$sel")) 
     echo "${arr[@]}" 
done 

печатает

L 50 CA 
K 117 CB 
K 46 CE 2 
V 9 CE 1 
+0

Удивительная благодарность. Все, что мне нужно было сделать, это комбинировать '$ {arr [2]} $ {arr [3]}'. Отличное решение. – PhysicalChemist

2

Bash единственное решение:

for sel in L50CA K117CB K46CE2 V9CE1; do 
    [[ "$sel" =~ "^(\w)([0-9]+)(.*)" ]] 
    printf '%s - ' "${BASH_REMATCH[@]}" 
    printf \\n; 
done 
1

В ударе с использованием string manipulation:

~$ sel1=L50CA 
~$ part1=$(expr match $sel1 "\([A-Z]\+\).*") 
~$ part2=$(expr match $sel1 "[A-Z]*\([0-9]\+\).*") 
~$ part3=$(expr match $sel1 "[A-Z]*[0-9]*\([A-Z]*\)") 
~$ echo $part{1,2,3} 
L 50 CA 
~$ arr=($part{1,2,3}) 
~$ echo ${arr[@]} 
L 50 CA 
+0

Я даже не знал, что струнные манипуляции существуют в bash ... как изящные. Спасибо за отличное решение. – PhysicalChemist

+0

Это не 'bash', это' expr'. –

+0

@EtanReisner http://en.wikipedia.org/wiki/Expr показывает, что он включен в оболочку как встроенная команда. (Здесь 'type expr' дает' expr is/usr/bin/expr' хотя.) – steffen