Как получить строку до цикла в Bash?
Я работаю над сценарием сжатия файлов. Я хочу сделать "пока цикл", пока содержимое переменной не соответствует шаблону. Скрипт использует zenity. Это основная часть:
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
Я хочу, чтобы он принимал строку, содержащую цифры, оканчивающиеся на "k" или "m" (но не оба), и не принимал строку, начинающуюся с "0".
Шаблон в порядке?
2 ответа
$ 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]$'
Но это некрасиво.
Редактировать:
Более длинный пример:
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.
Вы не хотите обратных цитат в until
линия. Вы могли бы написать:
until grep -E "$pattern" "$part"
do
...body of loop...
done
Или вы можете добавить аргументы grep
подавить вывод (или отправить вывод /dev/null
). Как написано, скрипт пытается выполнить вывод grep
команда и использовать статус успеха / неудачи этого (не grep
per se) как указание, продолжать ли цикл или нет.
Кроме того, ваш шаблон требует некоторой работы. Это:
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
, конечно.