Будь-який текстовий редактор, який може застосувати певну математику до заміни тексту?


15

У мене великий XML-файл

<obj param="2542">
<obj param="2333">
<obj param="6433">

Мені потрібно збільшити всі значення "парам" на деяку кількість. Я можу зіставити числа, які мені потрібні при пошуку regexp у багатьох редакторах, але як застосувати певну математику до заміни?


1
Яка операційна система? Чи були б ви задоволені сценарієм оболонки (що було б досить просто)? У всякому разі, я впевнений , що vimі emacsможе зробити такого роду речі, але це може зажадати написання сценарію , а не з допомогою однієї команди.
frabjous

@frabjous під windows. Я б краще не писав нічого, якщо це можливо. Але якщо ви опублікуєте сценарій оболонки, я впевнений, що він буде корисний багатьом.
серг

Відповіді:


18

Після того, як трішки побігати, виявляється, що vim може це зробити за допомогою однієї команди, без написання сценарію. Наприклад, щоб додати 50 до всіх цифр, які <obj param="ви можете використати:

:%s@<obj param="\(\d\+\)@\='<obj param="' . (submatch(1) + 50)@g

Дозвольте мені це зламати.

: - загальний спосіб перейти в / командний рядок у режимі vim.

%засоби, що знаходяться в межах всього документа; ви можете поставити діапазон чисел, наприклад, 1,50просто зробити це протягом перших 50 рядків.

s це скорочення для заміни (ви можете написати ціле слово, якщо хочете)

@- роздільник; ви можете використовувати будь-який інший символ до тих пір, поки це не в тому, що ви шукаєте. Просто використовуйте його три рази. (Синтаксис схожий на sed.)

Все, що стосується наступного появи роздільника @, - це шаблон reg ex для пошуку, у цьому випадку <obj param="слідує \d\+, яке є будь-якою кількістю цифр. The \(and \)are there, щоб встановити всю цю послідовність цифр як єдину групу reg reg, яка б відповідала зворотним посиланням на зразок \1, або submatchкоманді vim .

Потім роздільник @відзначає те, що випливає з тексту заміни.

Тут \=на початку означає підміняти результат деяким оціненим виразом, а не reg ex шаблоном або рядком, що є ключовим тут.

Тоді ми маємо '<obj param="'для початку текст заміни. Далі .випливає функція vim для об'єднання рядків.

submatch(1)- це вбудована функція vim, яка може бути використана лише в команді підстановки і повертає рядок, такий же, як і регулярний вираз \1; ви б використали submatch(2)для еквівалента регулярних виразів \2тощо. ( \0Це весь ваш смак варіант оформлення, але ми не хочемо , щоб тут) . В \(і \)в шаблоні пошуку використовуються для розмітки , що вважається submatch(1).

Звідси (submatch(1) + 50)виходить результат додавання 50 до числа, яке цифри, що слідують <obj param="у формі пошуку шаблону.

Розмежувач @знову використовується для позначення кінця тексту заміни.

Прапор gвикористовується, щоб зробити заміни глобальними; Ви можете пропустити це, якщо хочете замінити перший екземпляр у кожному рядку.

Ви, мабуть, можете звідти розробити, як додавати різні числа, або віднімати, або ділити тощо.


Це чудово, у мене був файл GPX, який був пошкодженим, оскільки значення довготи були абсолютно недійсними. На щастя, широта була в порядку, тому за допомогою карти я зміг розібратися, яким має бути перше правильне значення, зробити деякі математичні показники та обробити, що мені потрібно відняти 4294.567548 з кожного значення, щоб правильно його встановити. Єдиним каменем спотикання було те, що цей метод не працював на число з плаваючою комою, тому я просто робив кожну сторону десяткової крапки як окремі підстановки, одну -4294 та одну -567548.
stuff

7

У Emacs (починаючи з версії 23): використовуйте \,для виконання довільного коду Lisp при заміні regexp . Наприклад, для квадратних чисел, які ви могли б використовувати

M-x replace-regexp
param="\([0-9]+\)"
param="\,(* \#1 \#1)"

У Vim: почати текст заміни \=(див. :help sub-replace-special). Наприклад, для квадратних чисел:

s!param="\([0-9]\+\)"!\='param="'.submatch(1)*submatch(1).'"'!

Кілька редакторів дозволяють вам робити такі речі за допомогою макросів: визначте макрос, який 1. шукає наступний збіг та 2. виконує заміну (використовуючи зовнішній інструмент для арифметики, якщо це необхідно); повторіть макрос стільки разів, скільки у вас є збігів.


Занижена відповідь. Короткий і ви охоплюєте 2 редактори + загальний випадок.
дерев

1

Ви можете використовувати vim, щоб зробити це для вас. Просто відкрийте файл і запишіть макрос . Приклад: пошук будь-якого числа

/[0-9]{1,}

потім натисніть q і a (збережіть макрос в регістрі a). Після цього натисніть Ctrl-X (збільшивши число на 1) і натисніть n (для наступного результату пошуку) потім. Після цього знову натисніть q, щоб зберегти макрос. Тепер ви можете застосувати макрос до наступного числа, натиснувши @ + a. Це змінить поточне число і перейде до наступного. Повторивши це або використовуючи x @ a, ви можете повторити це x разів.

Що ж, цього опису може бути недостатньо, щоб показати, як це можна зробити. Просто зверніться до підручника, що описує механізм макросистеми vim.


Що робити, якщо мені потрібно змінити число не на 1, а на мільйон? Чи, можливо, використовувати якесь множення / ділення?
серг

1
Це легко, якщо ви хочете додати константу x до кожного числа: x + Ctrl + a. Вам потрібно додати різні числа?
evnu
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.