Увеличьте числа в файле, используя sed и regexp - PullRequest
1 голос
/ 17 марта 2020

Я хочу увеличить все числа в файле на 1000 с помощью следующего шаблона:

'... comment_count') VALUES ( 15132, ...
'... comment_count') VALUES ( 15133, ...
'... comment_count') VALUES ( 16134, ...
.
.

Я хочу после вывода изменений быть таким:

'... comment_count') VALUES ( 16132, ...
'... comment_count') VALUES ( 16133, ...
'... comment_count') VALUES ( 17134, ...
.
.

Я пробовал что-то подобное, но не работает:

 sed -r 's/`comment_count`\) VALUES \( (\d+)/echo "\1\1$((\1+1000))\"/ge'  test.txt 

Ответы [ 3 ]

2 голосов
/ 17 марта 2020

Ответ предполагает, что все строки имеют формат, показанный в OP.

Следующий скрипт sed, запускаемый с sed -E -f plus1000 inputfile (-E должен использовать (, { и «лайки» вместо \(, \{ и других) выполняет задание:

# this file is name plus1000
s/([^0-9][0-9]*)([0-9])([0-9]{3})/\1\n\2\n\3/
:a
h
s/.*\n(.)\n.*/\1/
y/0123456789/1234567890/
G
/^0/{
  s/0\n(.*)(.)\n.\n(.*)/\1\n\2\n0\3/
  ta
}
s/(.)\n(.*)\n.\n(.*)/\2\1\3/

Объяснение:

  1. команда top s/…/…/ включает четвертая значащая цифра между двумя новыми строками \n;
    • содержимое пространства шаблона будет соответствовать ^.*\n[0-9]\n.*$
    • содержимое пространства удержания не имеет значения (нам все равно, что это за содержимое)
  2. метка :a отмечает линию, где начинается do-while l oop;
    • без изменений в шаблоне и пробелах
  3. команда h копирует содержимое пространства шаблона (текущей строки в том виде, в каком она стала), перезаписывая все, что было в этом;
    • пространство шаблона не изменилось
    • пространство удержания равно пространству шаблона
  4. эта другая команда s/…/…/ удаляет все, что окружает ди git, который был «выделен» на шаге 1;
    • пространство шаблона содержит только одну ди git, т. Е. Оно имеет вид ^[0-9]$
    • пространство удержания не изменяется
  5. the * Команда 1055 * преобразует каждое число di git в его преемник, за исключением 9, которое становится 0, что означает, что следующее число di git слева также должно быть увеличено на 1;
    • пространство шаблона содержит только одну ди git, которая увеличивается на 1 относительно предыдущего шага
    • пространство удержания не изменяется
  6. команда G добавляет содержимое пространства удержания к шаблону sapce
    • пространство удержания не изменяется
    • пространство шаблона - это di git, только что увеличенное на шаге 5, с последующим символом новой строки \n, за которым следует содержимое пробела
  7. /^0/ ограничивает действие команд, сгруппированных в { и }, только Пространство шаблонов, которое имеет начальный 0 (который ранее был 9)

    7.1. третья команда s/…/…/ удаляет новую строку, добавленную на шаге 6, и перемещает две другие новые строки вокруг следующей (слева) цифры 7.2. команда t в тестах, если на самом деле произошла предыдущая замена, и, если это так, она передает управление в строку, помеченную на шаге 2 (фактически в строку после нее, так как :a не выполняет никаких действий)

  8. если мы достигнем здесь, мы добавили 1 к ди git, отличному от 9, поэтому дальнейшая обработка не требуется, поэтому четвертая и последняя команда s/…/…/ переупорядочивает фрагменты и удаляет символы новой строки.

2 голосов
/ 18 марта 2020

Это может работать для вас (GNU sed):

sed 's/[0-9]\+/$((&+1000))/g;s/.*/echo "&"/e' file

Заменить каждый набор чисел выражением bash цифра c. Оцените всю строку с помощью команды echo.

2 голосов
/ 17 марта 2020

sed не может выполнять замену или математику.

Вы можете использовать это perl решение:

perl -pe "s~(comment_count'\)\h+VALUES\h+\(\h+)(\d+)~\$1.(\$2+1000)~e" file

'... comment_count') VALUES ( 16132, ...
'... comment_count') VALUES ( 16133, ...
'... comment_count') VALUES ( 17134, ...
...