Сменить текст вокруг знака равенства
Есть ли простой способ перевернуть код вокруг знака равенства в vi/vim?
Например: я хочу это сделать:
value._1 = return_val.delta_clear_flags;
value._2._1 = return_val.delta_inactive_time_ts.tv_sec;
value._2._2 = return_val.delta_inactive_time_ts.tv_nsec;
value._3 = return_val.delta_inactive_distance_km;
(...)
в это:
return_val.delta_clear_flags = value._1;
return_val.delta_inactive_time_ts.tv_sec = value._2._1;
return_val.delta_inactive_time_ts.tv_nsec = value._2._2;
return_val.delta_inactive_distance_km = value._3;
(...)
в LOT строк в файле.
Я знаю, что это кажется немного тривиальным, но я часто сталкивался с множеством случаев, когда кодировал, где мне нужно было это делать в прошлом, и у меня никогда не было хорошей идеи/способа сделать это, не требовал много ввода в vim или писал awk script. Я бы подумал, что это возможно с помощью одного лайнера в vi.
Пояснения к однострочным линиям очень приветствуются и будут сильно рассмотрены, когда я выберу свой принятый ответ.:)
Ответы
Ответ 1
Что-то вроде этого:
:%s/\([^=]*\)\s\+=\s\+\([^;]*\)/\2 = \1
Возможно, вам придется немного поиграть с ним, если у вас более сложный код, чем тот, который вы показали в этом примере.
EDIT: Объяснение
Мы используем команду s/
find /
replace. Эта часть найдет нас:
- самая длинная строка, состоящая из знаков ничего, но равных, выраженная
[^=]*
...
- ... за которым следует одно или несколько пробелов,
\s\+
(дополнительный \
перед +
- это vim oddity)
- ... затем
=
и снова любое количество пробелов, =\s\+
- ... за которым следует самая длинная строка символов с точкой с запятой,
[^;]*
Затем мы запишем пару скобок для сохранения материала, который нам понадобится, чтобы построить заменяющую строку, что синтаксис \(
stuff \)
И, наконец, мы используем захваченные строки в заменяющей части команды s/
find /
replace: \1
и \2
.
Ответ 2
Для интереса, вот как я сделал это как записанный макрос:
qq0"+df=xA<BACKSPACE> = <ESC>"+pxi;<ESC>jq
Формирование того, что на первой строке устанавливает макрос "q" для выполнения необходимых действий. Затем на каждой последующей строке вы можете выполнить макрос, набрав:
@q
или, скажем, вы хотите применить макрос к следующим 10 строкам:
[email protected]
Я всегда нахожу макросы проще для быстрого переключения, как это, чем вычислять регулярное выражение, потому что они по сути являются расширением того, как я буду делать это вручную.
Изменить. Дэн Олсон указывает в своем комментарии, что если вы хотите применить макрос к ряду строк, например строки 6-100, вы можете ввести следующее. Я не знаю, есть ли более сжатый синтаксис, который не требует соответствия шаблону ". *".
:6,100g/.*/normal @q
Объяснение макроса
- кв.кв
- начать запись в регистр q
- 0
- "+ ДФ =
- удалить до '=' и поместить текст в регистр "+"
- х
- удалить лишнее пространство
-
- перейти к концу строки и войти в режим вставки
-
<BACKSPACE>
= <ESC>
- Удалить точку с запятой, вставить знак равенства и пробел
- "+ р
- вставьте тест, скопированный ранее в регистр '+'
- XI
<ESC>
- вставьте конечную точку с запятой
- J
- переместитесь на следующую строку, чтобы повторно применить макрос
- д
Ответ 3
:%s/^\s*\(.\{-}\)\s*=\s*\(.\{-}\)\s*;\s*$/\2 = \1;/
должен работать хорошо.
Ответ 4
:%s/\([^ =]*\)\s*=\s*\([^;]*\);/\2 = \1;/