седь цифры с необязательным десятичным и обратным ссылкам - PullRequest
0 голосов
/ 14 декабря 2018

У меня есть простой ввод, такой как:

11111(n)
222222(p)
33333333(:)

Я могу использовать обратную ссылку sed, чтобы поменять круглые скобки с такими цифрами:

sed -e 's/\([[:digit:]]*\)\((.*)\)/\2 \1/' file

, которые производят

(n) 11111
(p) 222222
(:) 33333333

Это круто!

Но с потенциальными десятичными цифрами все стало сложнее, например

11111(n)
11111.111(n)
2222222.22(p)
33.3333333(:)

Я пробовал много команд, например

sed -e 's/\([[:digit:]]*(\.[[:digit:]]*?)\)\((.*)\)/\2 \1/' file
sed -e 's/\([[:digit:]]*\.?[[:digit:]]*?)\)\((.*)\)/\2 \1/' file
sed -e 's/\([[:digit:]]*\.*[[:digit:]]*)\)\((.*)\)/\2 \1/' file
sed -e 's/\([[:digit:]]*.*[[:digit:]]*)\)\((.*)\)/\2 \1/' file

Выводтребуемый:

(n) 11111
(n) 11111.111
(p) 2222222.22
(:) 33.3333333

Обратите внимание, что цифры могут быть произвольной длины (от 1 до n цифр), а десятичные знаки (.) и десятичные цифры необязательны.

Кроме того, sed don 'Кажется, у него есть \d сокращение, как указано в stackexchange

Ответы [ 3 ]

0 голосов
/ 14 декабря 2018

Это становится довольно просто, когда вы знаете, что сопоставлять в выражении скобки POSIX с [:digit:].Все, что вам нужно сделать, это включить еще один ., чтобы выражение в скобках означало набор цифр вместе с .,

sed 's/\([[:digit:].]*\)\((.*)\)/\2 \1/' file

Также вам не нужно упоминать -e, потому что sed по умолчанию работает в режиме BRE (базовые регулярные выражения), а при -E включен режим ERE (расширенное регулярное выражение).Также \d не является допустимой конструкцией регулярного выражения, используемой любыми версиями sed (POSIX, GNU или FreeBSD) для сопоставления цифр.Я полагаю, это поддерживается в библиотеке PCRE, в которой вы можете использовать perl

perl -lne 'print "$2 $1" if /(\d+\.?\d*).*(\([^)]*\))/' file
0 голосов
/ 14 декабря 2018

Почему бы просто не использовать простой сбор?

sed -e 's/\([0-9.]*\)\((.*)\)/\2 \1/' file

Поскольку [0-9] и [: digit:] в основном одинаковы , но когда вы хотите включить другой символ, первый более интуитивно понятен.

Учитывая вторую мысль, в которой я вижу, что вы пытаетесь сопоставить допустимое число, то есть нет точки или только одну точку, таким образом, улучшенное значение sed будет следующим:

sed -r 's/([0-9]+(\.[0-9]+)?)(\(.*\))/\3 \1/' file

-r для поддержки +?в RE и поменяйте местами скобки.
Или используйте perl, чтобы избежать путаницы в расширении RE:

perl -lne 'print "$3 $1" if /(\d+(\.\d+)?)\s*(\(.*?\))/' file

Обновление: как Бенджамин В. упомянул в комментариях, [0-9] и [[: digit:]] - это не одно и то же, поэтому, если вы хотите рассмотреть возможные цифры на других языках, sed должен быть:

sed -r 's/([[:digit:]]+(\.[[:digit:]]+)?)(\(.*\))/\3 \1/' file
0 голосов
/ 14 декабря 2018

Вы можете использовать это sed:

sed -E 's/^([.[:digit:]]+)(\([^)]*\))/\2 \1/g' file

(n) 11111
(n) 11111.111
(p) 2222222.22
(:) 33.3333333

Здесь [.[:digit:]]+ будет соответствовать 1+ любой цифры или точки.

...