2013-05-02 8 views
3

Я работаю над скриптом, сжимающим файлы. Я хочу сделать «до цикла» до того, как содержимое переменной будет соответствовать шаблону. Сценарий использует зенит. Это основная часть:Как сгладить строку до цикла в bash?

part="0" 
pattern="^([0-9]{1}[0-9]*([km])$" 
until `grep -E "$pattern" "$part"` ; do 
    part=$(zenity --entry \ 
    --title="Zip the file" \ 
    --text "Choose the size of divided parts: 
(0 = no division, *m = *mb, *k = *kb)" \ 
    --entry-text "0"); 

    if grep -E "$pattern" "$part" ; then 
     zenity --warning --text "Wrong text entry, try again." --no-cancel; 
    fi 
done 

Я хочу, чтобы принять строку, содержащую цифры закончилась «к» или «т» (но не оба) и не принимают строку с начала «0».

Является ли образец нормально?

+0

Подождите, вопрос только в том, хорошо ли образец? Или у вас проблемы со всем скриптом? Если вы заботитесь только о шаблоне, вы можете значительно упростить вопрос, удалив не важные части. – Shahbaz

ответ

5
$ grep -w '^[1-9][0-9]*[km]$' <<< 45k 
45k 
$ grep -w '^[1-9][0-9]*[km]$' <<< 001023m 
$ grep -w '^[1-9][0-9]*[km]$' <<< 1023m 
1023m 

Не забудьте <<< в своем выражении, вы не grep'ing файл, но строка. Чтобы быть более POSIX-совместимой, можно также использовать:

echo 1023m | grep -w '^[1-9][0-9]*[km]$' 

Но это своего рода уродливый.

Edit:

Longer пример:

initmessage="Choose the size of divided parts:\n(0 = no division, *m = *mb, *k = *kb)" 
errmessage="Wrong input. Please re-read carefully the following:\n\n$initmessage" 

message="$initmessage" 

while true ; do 
    part=$(zenity --entry \ 
     --title="Zip the file" \ 
     --text "$message") 
    if grep -qw '^[1-9][0-9]*[km]$' <<< "$part" ; then 
     zenity --info --text 'Thank you !' 
     break 
    else 
     message="$errmessage" 
    fi 
done 

Кроме того, это не имеет прямого отношения к вопросу, но вы можете захотеть взглянуть на Yad, который делает в основном одни и те же вещи, Zenity делает, но имеет больше вариантов. Я использовал его много, когда мне приходилось писать сценарии Bash, и нашел его гораздо более полезным, чем Zenity.

+0

Спасибо. Я должен использовать zenity (это директива проекта). У меня проблема с рисунком. Я хочу, чтобы он принял то, что было сказано выше, и «0» (если нет разделения). – Nojas

+0

@Nojas: Я думаю, вы хотите это: 'grep -E '(^ ​​0 $ |^[1-9] [0-9] * [km] $)'' – michaelmeyer

+0

Он не работает ни для 0, ни для остальная часть рисунка. – Nojas

3

Вы не хотите, чтобы обратные кавычки в строке until. Вы могли бы написать:

until grep -E "$pattern" "$part" 
do 
    ...body of loop... 
done 

Или вы можете добавить аргументы grep подавить вывод (или направить вывод /dev/null). Как написано, сценарий пытается выполнить вывод команды grep и использовать статус успеха/отказа этого (а не grep как таковой) как указание на продолжение цикла или нет.

Кроме того, ваш рисунок нуждается в некоторой работе. Это:

pattern="^([0-9]{1}[0-9]*([km])$" 

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

pattern='^[1-9][0-9]*[km]$' 

Одиночные кавычки, как правило, более безопасны, чем двойные кавычки для таких вещей, как регулярные выражения.


Я просто хочу, чтобы проверить, если моя переменная называется part хорошо сформированным после записи его в окне ввода Zenity. Я просто понял, что grep нужен файл, но мой part - это переменная, инициализированная в этом скрипте. Как сейчас ладить?

В bash, вы можете использовать оператор <<< для перенаправления из строки:

until grep -E "$pattern" <<< "$part" 

В большинстве других оболочек, вы бы написать:

until echo "$part" | grep -E "$pattern" 

Это также работает в bash , конечно.

+0

Спасибо. Я просто хочу проверить, хорошо ли сформирована моя переменная под названием «part» после ее записи в диалоговом окне ввода zenity. Я просто понял, что grep нуждается в файле, но моя «часть» - это переменная, инициализированная в этом скрипте. Как сейчас ладить? – Nojas