LinuxForum.Fans
Тема

Прошу помощи с sed

Автор: ufomen 5 сообщений 3682 просмотров
#85688

Всем привет,
есть список IP вида:

text

# cat /tmp/mail2
123.25.64.6.smtp > 92.45.59.112.58101
92.45.59.112.58101 > 123.25.64.6.smtp
123.25.64.6.smtp > 92.45.59.112.58101

пытаюсь sed рубануть все с конца строки до первой точки:

text

cat /tmp/mail2 |sed 's/\..*$//'

По идее
$ знак конца строки,
.* - любые символы в любом кол-ве
\. экранированный знак точки

Тоесть это как-бы должно значить "заменить все с конца стоки (с права на лево) до первой найденной - точки ничем"

НО на выходе получаю

text

123
92
123

Почему оно заменяет все до последней встретившейся точки если считать с конца строки?

С sed опыта мало, погуглил но не пойму почему оно ТАК работает.

#85781

sed 's/\.\[^.\]*$//'

#85868
CyberDaemon написал:
sed 's/\.\[^.\]*$//'

Попробывал, у меня Ваша конструкция выводит неизмененный список:

text

# cat /tmp/mail2 |sed 's/\.\[^.\]*$//'
123.25.64.6.smtp > 92.45.59.112.58101
92.45.59.112.58101 > 123.25.64.6.smtp
123.25.64.6.smtp > 92.45.59.112.58101

P.S.

text

# cat /etc/issue
CentOS release 4.8 (Final)
Kernel \r on an \m

# rpm -q sed sed-4.1.2-7.el4

#86326

Ну в общем решил сам но не без помощи ))

Варианты:

text

awk -F'.' '{print $1"."$2"."$3"."$4}'

sed -s "s/\([0-9]*\.[0-9]*\.[0-9]*\.[0-9]*\)\(\.[0-9]*\)/\1/"

sed -s "s/\(.*\)\(\..*$\)/\1/"

Мде, регулярки учить нужно...

P.S. Как поставить РЕШЕНО не знаю )

#86960
ufomen написал:
По идее
$ знак конца строки,
.* - любые символы в любом кол-ве
\. экранированный знак точки

Тоесть это как-бы должно значить "заменить все с конца стоки (с права на лево) до первой найденной - точки ничем"

всё верно. гуглите на тему "жадность звёздочким в sed". звёздочка пожирает не до первой, а всё, что сможет - точка == любой символ, в том числе и точка. Вот она у вас всё и пожрала. Ибо жадная.

ищите не "любой символ", а "любой кроме точки":
[console]$ echo "123.25.64.6.smtp > 92.45.59.112.58101" | sed 's/\.[^.]*$//'
123.25.64.6.smtp > 92.45.59.112
[/console]
можно подойти к проблеме с другой стороны: пусть звёздочка жадная, заставим её жрать все точки, кроме одной! и выделим то, что пожрётся:
[console]$ echo "123.25.64.6.smtp > 92.45.59.112.58101" | sed -r 's/(.*)\..*/\1/'
123.25.64.6.smtp > 92.45.59.112
[/console]
тут 2 звёздочки, регулярка работает слева-направо, потому первая звёздочка жрёт всё, кроме одной точки (мы её явно указали). Это последняя точка, т.к. звёздочка жадная. Второй звёздочке точек уже не достанется.

ufomen написал:
Мде, регулярки учить нужно...

а то!?
то, что вы написали, хоть и работает, но слишком много лишнего...

Войдите или зарегистрируйтесь, чтобы ответить.