Извлечение чисел из строки с помощью sed и регулярные выражения
еще один вопрос для экспертов sed.
у меня есть строка, представляющая собой путь, который будет иметь два числа в нем. Пример:
./pentaray_run2/Trace_220560.dat
мне нужно извлечь второе из этих чисел-то есть 220560
Я (с некоторой помощью форумов) смог извлечь все номера вместе (т. е. 2220560) с:
sed "s/[^0-9]//g"
или извлечь только первое число с:
sed -r 's|^([^.]+).*$||; s|^[^0-9]*([0-9]+).*$||'
но мне нужен второй номер!! Любая помощь очень ценится.
PS номер, который я ищу, всегда является вторым номером в строке.
4 ответов
это нормально?
sed -r 's/.*_([0-9]*)\..*//g'
С вас пример:
kent$ echo "./pentaray_run2/Trace_220560.dat"|sed -r 's/.*_([0-9]*)\..*//g'
220560
если grep
приветствуется :
$ echo './pentaray_run2/Trace_220560.dat' | grep -oP '\d+\D+\K\d+'
220560
и более портативный с Perl
С тем же регулярным выражением :
echo './pentaray_run2/Trace_220560.dat' | perl -lne 'print $& if /\d+\D+\K\d+/'
220560
Я думаю, что подход чище и надежнее, чем использование sed
вы можете извлечь последние числа с помощью этого:
sed -e 's/.*[^0-9]\([0-9]\+\)[^0-9]*$//'
легче думать об этом задом наперед:
- в конце строки сопоставьте ноль или более символов без цифр
- матч (и захват) один или несколько символов цифр
- матч по крайней мере один не-значный символ
- сопоставьте все символы с началом строки
Часть 3 матча, где происходит" магия", но это также ограничивает ваши матчи должны иметь по крайней мере не цифру перед номером (т. е. вы не можете сопоставить строку только с одним числом, которое находится в начале строки, хотя есть простой обходной путь вставки не цифры в начало строки).
магия состоит в том, чтобы противодействовать жадности слева направо .*
(часть 4). Без части 3 Часть 4 потребляла бы все, что может, включая числа, но с ней сопоставление гарантирует, что оно остановится, чтобы позволить по крайней мере не-цифра следовать цифрой, котор нужно уничтожить частями 1 и 2, позволяющ номеру быть захваченным.
Это может сработать для вас (GNU sed):
sed -r 's/([^0-9]*([0-9]*)){2}.*//' file
это извлекает второе число:
sed -r 's/([^0-9]*([0-9]*)){1}.*//' file
и это извлекает первый.