Сценарий:
|).Возможно ли с помощью Vim удалить все данные из второго канала до конца строки для всего файла? Там примерно 150 000 строк, так что делать это вручную будет привлекательно только мазохисту ...
Например, измените следующие строки с:
1111|random sized text 12345|more random data la la la|1111|abcde
2222|random sized text abcdefghijk|la la la la|2222|defgh
3333|random sized text|more random data|33333|ijklmnop
к:
1111|random sized text 12345
2222|random sized text abcdefghijk
3333|random sized text
Я уверен, что это можно как-то сделать ... Надеюсь.
Обновлено: Я должен был упомянуть, что я запускаю это в Windows XP, поэтому у меня нет доступа к некоторым из упомянутых команд * nix (cut не распознается в Windows).
Я думал об этом. Я просто должен быть осторожен, устанавливая на свой компьютер нестандартные вещи. К счастью, они дают нам больше свободы действий, чем обычный пользователь.
См. Также аналогичный (более свежий) вопрос «Как удалить текст после указанного символа в Vim».





:%s/^\v([^|]+\|[^|]+)\|.*$/\1/
Включает "очень волшебный" режим для этого регулярного выражения. Это позволяет избежать использования парных скобок, плюсов и прочего с помощью обратной косой черты. Смотрите: h / \ v
Я обнаружил, что vim не очень хорош для обработки очень больших файлов. Я не уверен, насколько велик ваш файл. Может быть, cat и sed вместе сработают лучше.
В любом случае, 150000 строк этого типа должно быть в порядке с Vim.
У меня было более 100 МБ файлов (сгенерированных), и Vim - единственный редактор, который я видел, который их обрабатывает ... Я не знаю, почему у вас могут возникнуть проблемы с этим!
С этим файлом поработал нормально =)
И я отредактировал лог-файлы размером 20 ГБ с помощью регулярных выражений vim. Да, это было медленно. Но сделал свое дело.
Вот решение sed:
sed -e 's/^\([^|]*|[^|]*\).*$/\1/'
Зачем использовать Vim? Почему бы просто не бежать
cat my_pipe_file | cut -d'|' -f1-2
Если вам не нужно использовать Vim, другой альтернативой будет команда unix cut:
cut -d '|' -f 1-2 file > out.file
Вы также можете записать макрос:
qq02f|Djq
а затем вы сможете воспроизвести его с помощью 100@q, чтобы запустить макрос на следующих 100 строках.
Макро объяснение:
qq: запускает запись макроса;0: переходит к первому символу строки;2f|: находит второе вхождение символа | в строке;D: удаляет текст после текущей позиции до конца строки;j: переход к следующей строке;q: завершает запись макроса.Это преждевременно перестанет работать, если в какой-либо строке нет двух | на нем, но работает иначе.
Вы также можете:
:%s/^\([^\|]\+|[^\|]\+\)\|.*$/\1/g
Это отфильтрует все строки в буфере (1,$) через вырез, чтобы выполнить задание:
:1,$!cut -d '|' -f 1-2
Чтобы сделать это только в текущей строке, попробуйте:
:.!cut -d '|' -f 1-2
Еще один способ сделать то же самое в Vim:
%s/^\(.\{-}|\)\{2}\zs.*//
%s/^\(.\{-}\zs|\)\{2}.*// " If you want to remove the second pipe as well.
На этот раз регулярное выражение соответствует как можно меньшему количеству символов (\{-}), за которыми следует |, и дважды (\{2}), они игнорируются, чтобы заменить весь следующий текст (\zs) ничем (//).
То же самое. Приятно, что этот ответ на самом деле немного объясняет, что он делает.
Вы можете использовать :command для создания пользовательской команды для запуска подстановки:
:command -range=% YourNameHere <line1>,<line2>s/^\v([^|]+\|[^|]+)\|.*$/\1/
Используйте Awk:
awk -F"|" '{$0=$1"|"$2}1' file
Вместо подстановки можно использовать команду :normal для повторения
последовательность из двух команд нормального режима на каждой строке: 2f|, прыжок
ко второму символу | в строке, а затем к D, удалив
все до конца строки.
:%norm!2f|D
Или даже :%no<S-Tab>2f|D. На мой взгляд, ваш ответ на сегодняшний день лучший.
Установите команды * nix, чувак. Вы никогда не пожалеете об этом. Я использую cygwin на XP, но думаю, что в наши дни есть более открытые альтернативы.