2012-05-22 2 views
4

У меня есть несколько строк, которые я перехожу от excel к вики и хочу добавить теги ссылок для части текста в каждой строке, если в этом поле есть текст. Я начал преобразовывая работу и прийти к этой точке:VIM: Вставить текст с помощью regex

|10.20.30.9||x|-|| 
|10.20.30.10||x|s04|Server 4| 
|10.20.30.11||x|s05|Server 5| 
|10.20.30.12||||| 
|10.20.30.13||||| 

То, что я хочу, чтобы изменить четвертый столбец, например, из "s04" - "[[server: s04]]". Я не хочу добавлять скобки ссылок, если строка пуста, или если она содержит «-». Если «-» - большая проблема, я могу ее удалить.

Все мои попытки по регулярному выражению получить что-либо из строки заканчивается во всей заменяемой строке.

+0

Возможно, вам не понадобится регулярное выражение. Вы можете просто найти и заменить «s04» на «[[server: s04]]», правильно? –

+0

Но я хочу добавить текст во все строки, где есть текст в том же столбце, что и s04, а в столбцах до этого может содержаться текст, поэтому визуальный блок не работает. – user1410444

+0

Вам следует рассмотреть возможность использования 'awk', установки '|' как разделитель полей. – ArjunShankar

ответ

1

Позвольте мне порекомендовать следующую команду замены.

:%s/^|\%([^|]*|\)\{3}\zs[^|-]\+\ze|/[[server:&]]/ 
+0

Очень приятно! Это, наверное, самое простое и лучшее решение проблемы! – user1410444

+1

Я заметил одну проблему. Любая запись в столбце 4, содержащая один или несколько «-», получит ссылку, связанную с частью, до первой «-». Поскольку я решил удалить все записи только с помощью «-», регулярное выражение можно было бы изменить на:% s/^ | \% ([^ |] * | \) \ {3} \ zs [^ |] \ +/[ [server: &]]/ – user1410444

+0

@ user1410444: Я, вероятно, неправильно понял эту часть спецификации.Чтобы прояснить проблему: должна ли команда игнорировать строки, в которых четвертый столбец * обозначает * дефис или где он * содержит * дефис? –

4

Рассмотрите возможность использования awk сделать это:

#!/bin/bash 

awk -F'|' ' 
{ 
    OFS = "|"; 
    if ($5 != "" && $5 != "-") 
    $5 = "server:" $5; 
    print $0 
}' 

ПРИМЕЧАНИЕ: Я редактировал этот сценарий с первой версии. Этот текущий, ИМО, лучше.

После этого вы можете обработать его при помощи:

cat $FILENAME | sh $AWK_SCRIPTNAME 

Переключатель -F'|' говорит awk использовать | в качестве разделителя полей. Операторы if/else и printf довольно понятны. Он печатает поля, а «server:» добавляется к столбцу 5, только если это не "-" или "".

Почему столбец 5, а не столбец 4 ?: Потому что вы используете | в начале каждой записи. Таким образом, awk берет «первое» поле(), чтобы быть пустой строкой, которая считает, что должно было произойти до это первое |.

0

попробовать

:1,$s/|\(s[0-9]\+\)|/|[[server:\1]]|/ 

при условии, что ваш s04, S05 всегда S и номер

+0

разметка mediawiki, поэтому replacment должен быть '| [[server: \ 1]] |' – rampion

+1

Обратите внимание, что это заменит первый s04 в следующем «| 10.20.30.11 | s04 | x | s05 | Server 5 |». –

+0

@JohanSoderberg: Да, это будет, но я предположил, что ввод подобен данному примеру и поэтому не содержит s03 в первых столбцах. Но вы правы, конечно. – dwalter

3

Это, вероятно, лучше использовать AWK как пишет ArjunShankar, но это должно работать, если вы удалите "-";) Не получилось, чтобы он работал с ним там.

:%s/^\([^|]*|\)\([^|]*|\)\([^|]*|\)\([^|]*|\)\([^|]\+|\)/\1\2\3\4[[server:\5]]/ 

Это просто глупо. Первые 4 идентичны (соответствуют всем до 4 раз). Не получилось работать с {4}. Пятый соответствует строкам s04/s05 (просто требуется, чтобы он не был пустым, поэтому «-» необходимо удалить).

+0

проще было бы использовать '\ {3}' для соответствия первым трем. Вы также можете использовать '[^ - |] [^ |] *', чтобы пропустить случай только '-'. Кроме того, попробуйте использовать '\ zs', чтобы полностью не использовать первый раздел::':% s/^ \% (| [^ |] * \) \ {3} \) | \ zs \ ([^ - |] [^ |] * \)/[[server: \ 1]]/' – rampion

+0

+1 для ответа, который будет работать в' vim' – ArjunShankar

+0

Чтобы избежать использования большого количества групп, попробуйте использовать '\ zs' и' \ ze' , Чтобы соответствовать только словам (solvind the--issue), вы можете использовать следующее regex: '\ w \ {1,}' –

4

Это, кажется, чтобы сделать работу на образце вы даете там (с Vim):

%s/^|\%([^|]*|\)\{3}\zs[^|]*/\=(empty(submatch(0)) || submatch(0) == '-') ? submatch(0) : '[[server:'.submatch(0).']]'/ 
+0

Это работало как шарм !. Я решил удалить - в поле, что упростило суставы. – user1410444

0

Более простое замещение может быть достигнуто с этим:

%s/^|.\{-}|.\{-}|.\{-}|\zs\(\w\{1,}\)\ze|/[[server:\1]]/ 

    ^^^^^^^^^^^^^^^^^^^^     -> Match the first 3 groups (empty or not); 
         ^^^    -> Marks the "start of match"; 
          ^^^^^^^^^^^  -> Match only if the 4th line contains letters numbers and `_` ([0-9A-Za-z_]); 
            ^^^ -> Marks the "end of match"; 

Если _ персонаж похожий на -, может отображаться, но не подлежит замене, и используйте его в следующих выражениях: %s/^|.\{-}|.\{-}|.\{-}|\zs\([0-9a-zA-Z]\{1,}\)\ze|/[[server:\1]]/

2

Добавление немного большей читаемости к идеям gi другие:

:%s/\v^%(\|.{-}){3}\|\zs(\w+)/[[server:\1]]/ 

Работа выполнена.

Обратите внимание, как {3} указывает количество пропущенных столбцов. Также обратите внимание на использование \v для очень магия режим регулярного выражения. Это уменьшает сложность вашего регулярного выражения, особенно когда оно использует больше «специальных» символов, чем буквальный текст.

+0

Хороший! Я полностью забыл, что мы могли бы использовать {3} для уменьшения повторений. Проголосовать за это! –

+0

Это не совсем сработало. На некоторых строках, где четвертое поле пусто, но есть текст в пятом, пятый был помещен как ссылка. – user1410444