как сделать перестановку в строке

и другие vi-подобные редакторы

Модератор: /dev/random

Ответить
Аватара пользователя
ripke
Сообщения: 85
ОС: Ubuntu 9.04, x86_64

как сделать перестановку в строке

Сообщение ripke »

Есить список адресов. Отформатировал его к такому виду
1 2010-03-04 10:43:30|91.195.185.67
2 2010-03-04 21:12:22|212.95.58.200
3 2010-03-05 08:42:31|91.214.45.233
4 2010-03-05 09:03:15|95.168.191.81
5 2010-03-05 19:04:40|195.24.157.60
6 2010-03-05 22:09:27|91.214.45.233
7 2010-03-06 00:36:46|109.87.177.229
8 2010-03-06 20:22:06|173.26.129.227
9 2010-03-06 22:28:31|174.57.55.84
10 2010-03-08 01:40:06|91.201.64.11
Надо переместить ай пи адреса из конца строки в начало. Вот примерно так
10 91.201.64.11 2010-03-08 01:40:06|
Пока читаю книжку про вим, но, похоже еще не дошел до нужного места. Исключительно в vim! ))

Спасибо сказали:
Аватара пользователя
Nazyvaemykh
Сообщения: 438
Статус: Подопытный участник

Re: как сделать перестановку в строке

Сообщение Nazyvaemykh »

:help substitute

а именно что-то такое:
:substitute/^\([0-9]*\) \([^|]*|\)\(.*\)/\1 \3 \2/
¡ Страсть к разрушению есть творческая страсть!
Спасибо сказали:
Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current
Контактная информация:

Re: как сделать перестановку в строке

Сообщение drBatty »

ripke писал(а):
16.03.2010 09:42
Исключительно в vim!

ed и его потомки - sed и vim поддерживают команду замены: s, она способна заменять выражения, которые намного сложнее вашего (для вашего ответ уже дан). В "доке про vim" об этом только базывые понятия, ЕМНИП, вроде s/маша/Мария Владимировна/ - простейшая замена. Потому читайте про регулярные выражения.
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:
Аватара пользователя
Nazyvaemykh
Сообщения: 438
Статус: Подопытный участник

Re: как сделать перестановку в строке

Сообщение Nazyvaemykh »

drBatty, неправда.

В доке по vim есть и про регулярные выражения. Да, и есть, что почитать. Например, вот в 27-й главе про предопределенные классы символов и тому подобное. Опять-таки, специфное для vim и отсутствующее в vi. Среди примеров есть и не совсем тривиальные.

Да, регулярные выражения заслуживают особого изучения, но «доков vim'а» это чтиво не отменяет и не заменяет. (:
¡ Страсть к разрушению есть творческая страсть!
Спасибо сказали:
Аватара пользователя
ripke
Сообщения: 85
ОС: Ubuntu 9.04, x86_64

Re: как сделать перестановку в строке

Сообщение ripke »

Nazyvaemykh писал(а):
16.03.2010 10:14
:help substitute

а именно что-то такое:
:substitute/^\([0-9]*\) \([^|]*|\)\(.*\)/\1 \3 \2/

Код: Выделить всё

E486: Шаблон не найден: ^\([0-9]*\) \([^|]*|\)\(.*\)


А мое нечто ))

Код: Выделить всё

:s/\(....-..-..\) \(..:..:..|\) \([0-9]*\.[0-9]*\>/\)/\3 \1 \2/

Говорит, что

Код: Выделить всё

E488: Лишние символы на хвосте

Смешно. Объясните, чего это там лишнего. Вроде все логично: запомнил 3 буфера, а потом расставляю их в другом порядке (на первое место - третий, на второе - первый, на последнее - второй). Что за лишние символы на хвосте? 8-)
Спасибо сказали:
Аватара пользователя
/dev/random
Администратор
Сообщения: 5282
ОС: Gentoo

Re: как сделать перестановку в строке

Сообщение /dev/random »

ripke писал(а):
16.03.2010 14:24
А мое нечто ))

Код: Выделить всё

:s/\(....-..-..\) \(..:..:..|\) \([0-9]*\.[0-9]*\>/\)/\3 \1 \2/

Говорит, что

Код: Выделить всё

E488: Лишние символы на хвосте

Смешно. Объясните, чего это там лишнего. Вроде все логично: запомнил 3 буфера, а потом расставляю их в другом порядке (на первое место - третий, на второе - первый, на последнее - второй). Что за лишние символы на хвосте? 8-)

У вас 4 слэша вместо трёх:
ripke писал(а):
16.03.2010 14:24
s/\(....-..-..\) \(..:..:..|\) \([0-9]*\.[0-9]*\>/\)/\3 \1 \2/

Он будет пытаться заменить "\(....-..-..\) \(..:..:..|\) \([0-9]*\.[0-9]*\>" на "\)".
А "\3 \1 \2/" - это "лишние символы на хвосте".
Спасибо сказали:
Аватара пользователя
ripke
Сообщения: 85
ОС: Ubuntu 9.04, x86_64

Re: как сделать перестановку в строке

Сообщение ripke »

Да, это была нечаянная загогулина )). Теперь так
:s/\(....-..-..\) \(..:..:..|\) \([0-9]*\.[0-9]*\>\)/\3\1\2/
Говорит - шаблон не найден. Если по отдельности шаблны запускать, то они работают, а три не хотят.
Спасибо сказали:
Аватара пользователя
/dev/random
Администратор
Сообщения: 5282
ОС: Gentoo

Re: как сделать перестановку в строке

Сообщение /dev/random »

ripke писал(а):
16.03.2010 14:48
Да, это была нечаянная загогулина )). Теперь так
:s/\(....-..-..\) \(..:..:..|\) \([0-9]*\.[0-9]*\>\)/\3\1\2/
Говорит - шаблон не найден. Если по отдельности шаблны запускать, то они работают, а три не хотят.

А они в тексте точно разделены ровно одним пробелом, как в шаблоне?
Спасибо сказали:
Аватара пользователя
ripke
Сообщения: 85
ОС: Ubuntu 9.04, x86_64

Re: как сделать перестановку в строке

Сообщение ripke »

О, да, спасибо. Действительно нестыковочко ). Подстановка сработала таким образом
91.195 2010-03-0410:43:30|.185.67
С третим буфером как-то не очень получилось...
Спасибо сказали:
Аватара пользователя
ripke
Сообщения: 85
ОС: Ubuntu 9.04, x86_64

Re: как сделать перестановку в строке

Сообщение ripke »

Ура, вот рабочее решение.
:s/\(....-..-..\) \(..:..:..|\)\([0-9]*\.[0-9]*\.[0-9]*\.[0-9]*\)/\3 \1 \2/g
Напоследок хотелось бы кругозору ради узнать, есть ли какие альтернативы этой строке, учитывая, например, что кол-во символов может варьироваться? Спасибо всем.
Спасибо сказали:
Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current
Контактная информация:

Re: как сделать перестановку в строке

Сообщение drBatty »

ripke писал(а):
16.03.2010 15:18
Напоследок хотелось бы кругозору ради узнать, есть ли какие альтернативы этой строке, учитывая, например, что кол-во символов может варьироваться?

можно
например вместо
/\(....-..-..\) /
можно написать
/\([^ ]\+\) /
тут я ваши точки и минусы поменял на непробел, который повторяется как минимум один раз
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:
Аватара пользователя
ripke
Сообщения: 85
ОС: Ubuntu 9.04, x86_64

Re: как сделать перестановку в строке

Сообщение ripke »

О, спасибо. Я вот тут еще проще сделал
:s/\(.*.|\)\([0-9]*\.[0-9]*\.[0-9]*\.[0-9]*\)/\2 \1
Спасибо сказали:
Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current
Контактная информация:

Re: как сделать перестановку в строке

Сообщение drBatty »

ripke писал(а):
16.03.2010 15:35
\(.*.|\)

это эквивалентно \(.*\)

PS: у вас палка '|' только одна? и так всегда?
тогда достаточно просто переставить то, что после палки в начало строки.

ЗЗЫЖ точнее не так:
надо перенести то, что после палки на позицию после первого пробела:
s/ \(.*\)|\(.*\)/ \2 \1|/
так примерно...
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:
Аватара пользователя
ripke
Сообщения: 85
ОС: Ubuntu 9.04, x86_64

Re: как сделать перестановку в строке

Сообщение ripke »

Озадачился здесь. Есть, допустим, строка вида
434 2010-03-17 14:22:46 93.89.219.145 Mozilla/4.0 (compatible; MSIE 6.0; Windo ws NT 5.2; Win64; AMD64) http://sit.ru

задача - удалить все кроме ай пи, его поставить на первое место. Насколько понимаю, здесь снова придется через буфера делать, но как все это представить в виде шаблонов, не могу пока понять. Знаю только как записать айпи.
Спасибо сказали:
Аватара пользователя
ripke
Сообщения: 85
ОС: Ubuntu 9.04, x86_64

Re: как сделать перестановку в строке

Сообщение ripke »

Почему в ответ на это
:s/\(^.*\)\([0-9]*\.[0-9]*\.[0-9]*\.[0-9]*\)/\2 \1/
Я получил это
.89.219.145 434 2010-03-17 14:22:46 93 Mozilla/4.0 (compatible; MSIE 6.0; Windo ws NT 5.2; Win64; AMD64) http://sit.ru
хотя ожидал увидеть весь айпи в начале строки? почему 93 осталось?
Спасибо сказали:
Аватара пользователя
/dev/random
Администратор
Сообщения: 5282
ОС: Gentoo

Re: как сделать перестановку в строке

Сообщение /dev/random »

ripke писал(а):
20.03.2010 21:58
Почему в ответ на это
:s/\(^.*\)\([0-9]*\.[0-9]*\.[0-9]*\.[0-9]*\)/\2 \1/
Я получил это
.89.219.145 434 2010-03-17 14:22:46 93 Mozilla/4.0 (compatible; MSIE 6.0; Windo ws NT 5.2; Win64; AMD64) http://sit.ru
хотя ожидал увидеть весь айпи в начале строки? почему 93 осталось?

Потому что "*" - жадный модификатор (это официальный термин). Идущий первым, он захватывает столько символов, столько сможет, а следующие модификаторы довольствуются остатками. Этот \(^.*\) в данном случае захватывает всё до первой точки, поскольку то, что остаётся (".89.219.145 " и т.д.) вполне соответствует оставшейся части шаблона. Чтобы решить проблему, нужно сделать, чтобы оно не соответствовало. Например, явно потребовать пробел.
Спасибо сказали:
Ответить