LINUX.ORG.RU

1
Всего сообщений: 40

Задачка на регулярные выражения на Perl для изящного решения

Чего-то не могу сообразить как бы кратко и с помощью регулярных выражений сделать следующее:

Удалить из последовательности произвольной длины из точек и цифр последнюю точку и цифру. Если число одно - то вернуть пустую строку. Если не соответствует этому шаблону, то тоже пустую строку. Например,

1.2.3.115.95  - вернуть 1.2.3.115
27.4 - вернуть 27
6 - вернуть пустую строку ""
6.abcd.7.4 - вернуть пустую строку ""

Возникло на днях на практике. Долго думать было некогда и поскольку реально могли быть только варианты максимум с 4 цифрами просто ляпнул следующее:

sub parentcode
{
   my $s=$_[0]; 
   return $1 if ($s=~m/(\d+\.\d+\.\d+)\.\d+/g);
   return $1 if ($s=~m/(\d+\.\d+)\.\d+/g);
   return $1 if ($s=~m/(\d+)\.\d+/g);
   return "";
}

Но как-то оно говнокодисто выглядит. И не универсально. Между тем, что-то изящного универсального способа не могу придумать. Все какое-то нагромождение с циклами и поиском подстрок выходит.

Может можно в одну строчку и регуляркой?

Update: в коментах нашлись варианты

 ,

praseodim ()

Автодополнение и регулярки в pacman/yay

Здравствуйте, как мне сделать сабж? По дефолта его нет.

Дело в том, что раньше я устанавливал через Anarchy и там был сабж. Сейчас я установил руками и не могу понять, как мне это сделать. Я уже привык, так как к хорошему и удобному привыкается быстрее.

Допустим, я хлчу установить все, что начинается с xfce и заканчивается на plugin. pacman -S xfce*plugin не работает от слова совсем и pacman читает звёздочку как часть названия, а не как регулярку. На нажатие tab после pacman -S xfce не реагирует НИКАК. Из шеллов пробовал bash и zsh, все дополнения установил, не помогает, что можно сделать? Спасибо.

 , , ,

zagatov_lev ()

Как в bash заэскейпить строку, чтобы ее подставить в регулярное выражение?

Есть такой кусок кода:

insertAfter='#!/bin/bash'
fileName='./file.txt'

insertAfterEsc=`printf "%q" "$insertAfter"` 

cmd="sed '/"$insertAfterEsc"/,$ d' < "$fileName" > /tmp/sedHead.txt"
echo "$cmd" | bash


Переменная insertAfter - это строка, может быть с любыми символами, и ее содержимое надо подставить в sed для поиска. Поэтому для подстановки в sed используется переменная insertAfterEsc.

И мне нужно найти нормальный метод экранирования. Метод:
insertAfterEsc=`printf "%q" "$insertAfter"` 

Не работает как надо, потому что, например, не экранирует прямые слеши «/».

Вопрос: как экранировать строку, чтобы ее можно было подставить в sed, и все символы ее считались просто символами?

 , , ,

Xintrea ()

sed, \d, PCRE и поиск цифр

Я что-то не пойму: sed до сих пор не умеет работать со стандартом PCRE?

Опция "-r" (она же "-E") включает расширенные регвыры, но это не подмножество PCRE? В мануале написано «use extended regular expressions in the script», но не написано что подразумевается под этим extended.

Спрашиваю потому, что не могу через «\d» найти цифру даже если включить опцию -r/-E.

 , , ,

Xintrea ()

rename - поиск и замена

Ребята привет. Может кто знает как решить задачу.

  1. В папке «test» - присутствуют следующие файлы: te1st1.txt te2st2.txt te3st3.txt Как при помощи команды «rename» заменить цифры в середине названия на «-»? что получить на выводе следующие названия: te-st1.txt te-st2.txt te-st3.txt

  2. В папке «test» - присутствуют следующие файлы: test1.txt test2.txt test3.txt Как при помощи команды «rename» получить на выводе следующие названия: test(t1).txt test(t2).txt test(t3).txt

 , ,

webgamer ()

Как в Ansible в модуле lineinfile написать _рядом_ ссылку назад и переменную?

Я хочу через Ansible 2.7.7 заменить в файле один сегмент IP-адреса:

- name: Замена IP
  lineinfile:
    destfile: "{{ nerworkInterfacesFile }}"
    backrefs: yes
    regexp: '(^\s*?address\s*?192\.168\.1\.)(\d*?)'
    line:   '\1{{ item[1] }}'

Проблема в том, что Ansible не может корректно вставить ссылку назад \1, если после нее сразу идет не-пробельный символ. Результирующая строка заменяется парой случайных символов.

А если поставить пробел, вот так:
    line:   '\1 {{ item[1] }}'

То все отрабатывает правильно, вот только в IP-адресе тоже появляется пробел.

Вопрос: как в Ansible в модуле lineinfile написать ссылку назад, и сразу после нее содержимое переменной?

 , , ,

Xintrea ()

Как дописать нолик к ссылке назад, чтобы он остался ноликом (а не добавлялся к номеру ссылки)?

У меня такая проблема. Мне нужно найти регуляркой группу, после которого надо написать строку, начинающуюся с нолика. Делаю я это для плейбука Ansible:

  - name: Переключение сетевой маски доступа PostgreSQL для сетей IPv4
    lineinfile:
      destfile: /etc/postgresql/9.1/main/pg_hba.conf
      regexp: '(^host\s*all\s*all\s*)\d+\.\d+\.\d+\.\d+\/\d+\s*md5'
      line: '\10.0.0.0/0 md5'
      backrefs: yes

Проблема в том, что ссылка назад с номером 1 не определяется. Ansible думает, что я хочу использовать ссылку с номером 10.

Ошибка такая:


fatal: [arm2]: FAILED! => {«changed»: false, «failed»: true, «module_stderr»: «Shared connection to 192.168.111.102 closed.\r\n», «module_stdout»: «Traceback (most recent call last):\r\n File \»/tmp/ansible_AT9bap/ansible_module_lineinfile.py\", line 425, in <module>\r\n main()\r\n File \«/tmp/ansible_AT9bap/ansible_module_lineinfile.py\», line 417, in main\r\n ins_aft, ins_bef, create, backup, backrefs)\r\n File \«/tmp/ansible_AT9bap/ansible_module_lineinfile.py\», line 252, in present\r\n b_new_line = m.expand(b_line)\r\n File \«/usr/lib/python2.7/re.py\», line 266, in _expand\r\n return sre_parse.expand_template(template, match)\r\n File \«/usr/lib/python2.7/sre_parse.py\», line 789, in expand_template\r\n raise error, \«invalid group reference\»\r\nsre_constants.error: invalid group reference\r\n", «msg»: «MODULE FAILURE»}



Если я заменю вот так, то ошибки нет:

line: '\1a.b.c.d/e md5'

Вроде как обычные регулярки такие случаи правильно разруливают: например, если ссылки назад с номером 10 нет, будет использоваться номер 1, а 0 будет рассматриваться как символ. Но в Ansible это не так.

Вопрос: как обойти эту особенность, и написать ссылку назад \1 и после нее символ 0?

 , ,

Xintrea ()

Регулярка для нахождения в тексте более пяти URL - как?

Есть текст, в котором могут быть прописаны от 0 до бесконечности URL.

Нужно, чтобы PCRE регулярка сработала в случае, есть количество URL больше 5.

Я пробую так:

(https?:\/\/.*?){5,}

Но такое впечатление, что квантор {5,} не применяется к группе в скобках.

Как правильно написать выражение?

 ,

Xintrea ()

Grep и регулярное выражение

Добрый день!

Нарвался на статьи на Хабре, по Башу(по местным комментам я понял уже, что материал не ахти, но всё же). Есть там вот такой пример, «как вытащить первого пользователя из выдачи команды who» и записать в переменную:

logged_on=$(who | grep -i -m 1 $1 | awk ‘{print $1}’)

Как я не пытался выполнить этот код, всё тщетно. Во время выполнения ругается Grep:

Usage: grep [OPTION]… PATTERN [FILE]…

Понимаю, что проблема в том, что Grep’ом хотят вытащить первый элемент в первой строке, но Grep не умеет в ‘$0/$1/$2’ и т.д.

Статья на Хабре - есть перевод другой статьи, оригинала. Там эту задачу решают по-другому:

logged=$(who | awk -v IGNORECASE=1 -v usr=$1 ‘{ if ($1==usr) { print $1 }exit }’)

но в моём случае всё тоже тщетно, в переменную ничего не записывается. Почему? Определить не смог. Пробовал немного изменить код:

logged=$(who | awk ‘{BEGIN IGNORECASE=1; usr=$1} { if ($1==usr) { print $1 }exit }’)

но результат по прежнему нулевой.

Саму задачу я уже решил, совсем по другому, через костыль, но всё же хочу правильно всё понять и разобраться. Как решать задачу верно? Может у меня какой-то не сильно умный GREP, который не умеет в регулярные выражения, если я не спутал понятия конечно?

Update:

Прошу меня простить, на абзац ниже, написано, что скрипт будет вызываться с параметром(например, интересующий нас пользователь), который попадает в $1 и всё сразу работает. Не доглядел. Извините!

 , ,

vladstv ()

Упростить регулярное выражение

Привет, ЛОР!

Есть регулярное выражение:

4.13.0-(1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20|21)-.*

Каким образом можно заменить это на диапазон с 1 по 21 таким образом, чтобы регулярное выражение осталось читабельным?

 , ,

Deleted ()

Как заставить в Perl в регулярках считать концом строки и \n и \r\n

Столкнулся с подставой, что в nix-ах

if (m/(.{10,})$)/)
{
...
}

символ \r (0x0dh) не покрывается квантификатором $ . В данном примере я выделял из входного файла все строки из 10 или более символов, но обнаружил, что пропускаются строки из 9 символов. Если сделать dos2unix на такой файл с ними, то работает нормально.

Способ с альтернативой

m/(.{10,})(\r|$)/
не подходит, в смысле почему-то все-равно включает \r \r|\n тоже не получается.

Данный пример для иллюстрации проблемы (длину можно и иначе пытаться считать), реальный код несколько сложнее.

 ,

praseodim ()

Как регуляркой обрезать юникод за пределами U+FFFF (или починить его)

Всякие символы типа
🌨 🌡️ 🌬️→
Надо или вырезать целиком или починить, чтобы символы отображались в терминале. Минт 17.3 в браузере все работает.

 , ,

crutch_master ()

регулярки и поиск по условию

Дано строка

123;345;567

Нужно выцепить отдельно первое значение, отдельно второе, отдельно третье

Пишу:

цифры от 0 до 9 три раза искать до первого «;» один раз.

(([0-9]{3})(?=;)){1}

В результате выделяет два значения.

Как выбрать второе и третье?

 ,

sniper21 ()

Выделение числа из строки в выводе команды (Bash)

Приветствую всех. Имеется следующий скрипт:

#!/bin/sh
WAYSCAN=/usr/bin/wayland-scanner
WAYLAND_PROTOS=/usr/share/wayland-protocols
OUTPUT=gfx/common/wayland

if [ ! -d $WAYLAND_PROTOS ]; then
    WAYSCAN=/usr/local/bin/wayland-scanner
    WAYLAND_PROTOS=/usr/local/share/wayland-protocols
fi

if [ ! -d $OUTPUT ]; then
    mkdir $OUTPUT
fi

В переменной WAYSCAN хранится путь к утилите wayland-scanner. Необходимо получить версию этой утилиты и поместить её в другую переменную, однако вывод wayland-scanner --version выводит строку wayland-scanner 1.16.0. Мне нужно из этой строки выделить только число. Знаю что это можно сделать с помощью регулярки, но как не пытался - не получается. Может кто подсказать решение, пожалуйста? Только чтобы работало как в Linux, так и BSD

 , ,

Sunderland93 ()

Позор дебианщикам

Ну вот что это такое?

Получено 111 MB за 3мин 17с (567 kB/s)                                                                                                 
/usr/share/apt-listchanges/apt_listchanges.py:540: FutureWarning: Possible nested set at position 25
  email_re = re.compile(r'([a-zA-Z0-9_\+\-\.]+)@(([[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([a-zA-Z0-9\-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)')
И с учётом того, что сейчас как раз заморозка — эта дрянь наверняка просочится в новый штабле. Опять страдать будете, штаблеводы? :3

Ящитаю, валидация мыл регулярками не имеет смысла вообще, ибо существование мыла надёжно проверяется только отправкой токена на него + иногда временными костыльными способами у конкретных почтовиков; остальное — фуфло и оверинжиниринг. Максимум — можно наличие равлыка в строке проверить, потому что без него это не мыло 100%.

Я б пошёл дебианщикам пожаловался, но такое сплошь и рядом, толку-то. У них и без этого аврал. Поэтому притащил сюда, надо же наполнять толксы нетехническим контентом про Linux/Unix в противовес тому говну, которое толксозависимые сюда тащат.

 , , ,

Moondancer ()

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

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

1->01
2->02
3->03
...
9->09
10->10
11->11
...
100->100
и так далее

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

Или даже для этого специальная команда форматирования есть? Подскажите, пожалуйста.

 ,

piyavking ()

найти регулярной в строке совпадающий с паттернов кусок

странно, не работает. Почему?

cat test.sh

#!/bin/bash
T="this is base line"

[[ $T =~ "\bbase\b" ]] && echo "yes"

 ,

sniper21 ()

отрицание в регулярных выражениях

хочу отсеять *.sh скрипты чтобы не пролезали

nicefile.png

badfile.sh

Хочу это делать с конца строки, это возможно при помощи отрицания ^(?!sh)$ + обратного просмотра ^(?<!sh)$ ?

проверяю в онлайн проверяльщике, но не работает.

 

sniper21 ()

регулярной исключить цифру в начале имени файла

[^0-9] - это исключить от 0 до 9

а как указать, что-то относится только к первому символу?

 

sniper21 ()

Выбрать числа из строки

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

{"min": 12, "max": "123", bla"blabla"12d""123":_blabla}
Как из нее выбрать только трехзначные числа в двойных кавычках?

 ,

cr0 ()