Страницы

Поиск по вопросам

вторник, 28 января 2020 г.

Как узнать номер вхождения символа из регулярного выражения для заданной строки?

#регулярные_выражения #bash #sed


Как-то так:    

echo "абвгд" | sed 's/в/\1{фокус}/` # получим: aбв3гд


Т.е. буква "в" стоит третьей и этот то номер необходимо вычленить, это возможно?
    


Ответы

Ответ 1



Получилось как то так: echo "абвгд" | sed 's/\(.\)/\1\n/g' | sed -n 'p;/в/=' | sed -n 'H;${x;s/\n//g;p}' Первый sed разбивает строку на строки с отдельными символами. Второй - после строки с буквой "в" печатает ее номер. Третий - собирает символы обратно в строку. При наличии perl, это конечно было бы проще: echo "абвгд" | perl -Ca -pe 's/в/$&.(length($`)-1)/e'

Ответ 2



если делать одним вызовом интерпретатора sed, получается довольно многословно (но наверняка можно чуть-чуть сократить при острой необходимости). для подсчёта количества символов используется программа wc: $ echo "абвгд" | sed -r 's/в/&\n/;h;s/^/echo -n "/;s/\n.*/"|wc -m/e;G;s/^(.+)\n(.+)\n/\2\1/' небольшое пояснение по коду программы для интерпретатора sed: s/в/&\n/ — добавляем после искомого символа символ перевода строки \n. дальше мы будем использовать его как маркер h — сохраняем текущее содержимое pattern space (абв\nгд) в hold space (оно нам понадобится чуть позже) s/^/echo -n "/ — вставляем в начало pattern space строку echo -n " s/\n.*/"|wc -m/e: s/\n.*/"|wc -m/ — заменяем всё, начиная с символа \n (мы его добавили на первом шаге) до конца pattern space на строку "|wc -m. теперь в pattern space у нас получилось: echo -n "абв"|wc -m. если эту строку выполнить в оболочке, то она вернёт символ 3 (количество символов в строке абв) e — с помощью этого модификатора команды s мы как раз и передаём содержимое pattern space в оболочку, чтобы она выполнила это содержимое как команду. результат выполнения этой команды заменит текущее содержимое pattern space (и в pattern space у нас будет символ 3) G — эта команда добавляет в конец pattern space символ перевода строки, а затем содержимое hold space. в результате в patten space у нас получилась строка 3\nабв\nгд s/^(.+)\n(.+)\n/\2\1/ — выбираем всё до первого символа \n (т.е., строку 3) в первую группу, всё между первым и вторым символом \n (т.е., строку абв) — во вторую, а затем выводим группы в обратном порядке — сначала вторую, потом первую: абв, затем 3. а остаток строки (гд) остаётся нетронутым в результате получаем в pattern space строку абв3гд, что и требовалось.

Ответ 3



С использованием промежуточного "огорода" в виде awk: echo "abcde" | awk 'match($0, /d/) {print substr($0, 0, RSTART),RSTART,substr($0, RSTART+1, RLENGTH)}' | sed 's/ //g'

Комментариев нет:

Отправить комментарий