Что регулярное выражение используется с sed, чтобы изменить порядок слов в строке - PullRequest
1 голос
/ 24 апреля 2020

I wi sh для транспонирования некоторых слов в строке, используя выходные данные одной команды, переданной по конвейеру другой. Учитывая эти строки вывода:

v4l_compat  1.18.0  Apr 20  2020
vim 8.2.0491_1  Apr 20  2020
vsftpd-ssl  3.0.3_2 Apr 20  2020
webcamd 5.7.1.1 Apr 20  2020
webcamoid   8.7.1   Apr 20  2020
wireshark   3.2.3   Apr 20  2020

Я хочу произвести:

2020-Apr-20 v4l_compat 1.18.0
2020-Apr-20 vim 8.2.0491_1
2020-Apr-20 vsftpd-ssl 3.0.3_2  
2020-Apr-20 webcamd 5.7.1.1
2020-Apr-20 webcamoid 8.7.1
2020-Apr-20 wireshark 3.2.3

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

 echo 'vsftpd-ssl  3.0.3_2 Apr 20  2020' | sed -E 's/([\-\.|\d|\w]+\b)/\5-\3-\4 \1 \2/'
 sed: 1: "s/([\-\.|\d|\w]+\b)/\5- ...": \5 not defined in the RE

Но я никогда не смогу получить больше групп захвата, чем вся строка

 echo 'vsftpd-ssl  3.0.3_2 Apr 20  2020' | sed -E 's/([\-\.|\d|\w]+\b)/\1/'
 vsftpd-ssl  3.0.3_2 Apr 20  2020

Однако, когда я проверяю регулярное выражение в Rubular, используя 'py37-evdev 0.8.1_1 9 января 2020', я получаю этот результат:

Match 1
1.  py37-evdev
Match 2
1.  0.8.1_1
Match 3
1.  Jan
Match 4
1.  9
Match 5
1.  2020

И если я делаю то же самое на regex101.com, я получаю такой результат:

Match 1
Full match  0-10    py37-evdev
Group 1.    0-10    py37-evdev
Match 2
Full match  11-18   0.8.1_1
Group 1.    11-18   0.8.1_1
Match 3
Full match  19-22   Jan
Group 1.    19-22   Jan
Match 4
Full match  23-24   9
Group 1.    23-24   9
Match 5
Full match  25-29   2020
Group 1.    25-29   2020

Я вижу, что regex101 возвращает только одну группу с совпадениями внутри группа, но я не вижу, что я делаю неправильно, так что вместо этого я не получаю 5 групп. Я также не могу заставить группы совпадений перезапускаться при изменении строки.

Что мне нужно сделать, чтобы это работало?

Ответы [ 2 ]

2 голосов
/ 24 апреля 2020

Вам не нужен сложный матч по первой части.

echo "py37-evdev 0.8.1_1 Jan 9 2020" | sed -r 's/(.*) (\w+)[ ]+(\w+)[ ]+(\w+)/\2-\3-\4 \1/'
1 голос
/ 24 апреля 2020

Дано:

$ s="v4l_compat  1.18.0  Apr 20  2020
vim 8.2.0491_1  Apr 20  2020
vsftpd-ssl  3.0.3_2 Apr 20  2020
webcamd 5.7.1.1 Apr 20  2020
webcamoid   8.7.1   Apr 20  2020
wireshark   3.2.3   Apr 20  2020"

Конечно легко с awk:

$ echo "$s" | awk '{printf "%s-%s-%s %s %s\n", $5,$3,$4,$1,$2}'

Отпечатки:

2020-Apr-20 v4l_compat 1.18.0
2020-Apr-20 vim 8.2.0491_1
2020-Apr-20 vsftpd-ssl 3.0.3_2
2020-Apr-20 webcamd 5.7.1.1
2020-Apr-20 webcamoid 8.7.1
2020-Apr-20 wireshark 3.2.3

Если вы хотите sed Вы можете сделать:

$ echo "$s" | sed -e 's/\([^ ]*\)[ ]*\([^ ]*\)[ ]*\([^ ]*\)[ ]*\([^ ]*\)[ ]*\([^ ]*\)/\5-\3-\4 \1 \2/'

# same output...
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...