Как проанализировать / Sed несколько строк с выражением регулярного выражения - PullRequest
0 голосов
/ 30 апреля 2019

Я пытаюсь извлечь информацию из отказов файлов ovpn, чтобы обновить мой список серверов.Я нахожу способ извлечь информацию с помощью sed, и все работает, но я застреваю, когда пытаюсь извлечь данные для создания структуры каталогов.

У меня есть файлы внутри папки, например:

ch101.tcp443.ovpn
ch101.udp1194.ovpn
ch102.nordvpn.com.tcp443.ovpn
ch102.nordvpn.com.udp1194.ovpn
ch102.tcp443.ovpn
ch102.udp1194.ovpn

Теперь я хочу извлечь информацию для создания структуры каталогов, поэтому Я сделал регулярное выражение , чтобы извлечь всю необходимую мне информацию

Это работает со всеми имеющимися у меня файламии получает данные из имени файла.Таким образом, из "ch101.udp1194.ovpn" он извлекает "ch101" и "udp" в группы 1 и 2.

Но когда я пытаюсь заставить его работать с sed, у меня не получается.Я пытался разбить его на этапы, но даже когда только 1-я группа искала «ch101», он не работает:

echo 'ch101.udp1194.ovpn' | sed -rn 's/^([a-z\-]+\d{1,4})/\1/p'

Что я пропустил?Я не эксперт по sed, но я нахожу подобное выражение, которое работает, но это не так.

Моя последняя цель - создать каталог и хранить в нем всю необходимую информацию, поэтому:

for i in /opt/ovpn/*.ovpn ; do 
    [ -f "$i" ] || continue
    FIRST_ARG=$(echo $i | sed ...) # extract ch101
    SECOND_ARG=$(echo $i | sed ...) # extract udp
    FIRST_ARG_TEXT=$(echo $FIRST_ARG | sed ...) # extract text from FIRST_ARG
    FIRST_ARG_NUM=$(echo $FIRST_ARG | sed ...) # extract num from FIRST_ARG
    FIRST_ARG_NUM_4FORMAT=$(printf '%04i\n' $FIRST_ARG_NUM) # 4 digits for FIRST_ARG_NUM

    mkdir /opt/somedir/$FIRST_ARG_TEXT$FIRST_ARG_NUM_4FORMAT$SECOND_ARG
    cp ........
done

Итак, из ch101.udp1194.ovpn я закончу каталогом с именем

ch0101udp

Может быть, это не самый лучший и чистый способ, но мне кажется простым и максимальным, что мои знания могутдостичь

Любая идея или вопрос хорош для меня

Ps.Я нахожусь под busybox 1.30, так что это должно быть sh не bash

Ответы [ 2 ]

2 голосов
/ 30 апреля 2019

Пара проблем: sed не поддерживает множество escape-последовательностей классов символов, таких как \d, поэтому вам нужно указать их как [0-9].

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

Нечто подобное будет работать для вашей первой группы:

sed -En 's/^([a-z\-]+[0-9]{1,4}).*/\1/p'

Но на самом деле то, что вы должны делать, это использовать правильныеПрограмма для этого.Не уверен, что он доступен на Busybox, но awk может сделать все, что вы ищете:

echo 'ch101.udp1194.ovpn' | awk -F. '{a=$1; b=$(NF-1); gsub(/[0-9]/, "", a); gsub(/[0-9]/, "", b); gsub(/^[a-z-]+/, "", $1); printf("%s%04d%s", a, $1, b)}'

Вывод из ваших примеров данных:

ch0101tcp
ch0101udp
ch0102tcp
ch0102udp
ch0102tcp
ch0102udp

Объяснение:

awk -F. '{
    a=$1;                          # assign the first field to a
    b=$(NF-1);                     # assign the second last field to b
    gsub(/[0-9]/, "", a);          # remove numbers from a
    gsub(/[0-9]/, "", b);          # remove numbers from b
    gsub(/^[a-z-]+/, "", $1);      # remove letters from the first field
    printf("%s%04d%s", a, $1, b)   # output in desired format
}'
0 голосов
/ 30 апреля 2019

Это то, что вы пытаетесь сделать?

$ sed -n 's/\([^.]*\).*\.\([^0-9]*\)[^.]*\.[^.]*$/\1\2/p' file
ch101tcp
ch101udp
ch102tcp
ch102udp
ch102tcp
ch102udp

$ echo 'ch-onion1.nordvpn.com.tcp443.ovpn' | sed -n 's/\([^.]*\).*\.\([^0-9]*\)[^.]*\.[^.]*$/\1\2/p'
ch-onion1tcp

Если это так, то это будет работать с любым sed в любой оболочке на любой машине UNIX. Если нет, то отредактируйте ваш вопрос, чтобы уточнить ваши требования и предоставить точный ожидаемый результат для ваших различных заданных значений входных данных.

...