grep — Сложная команда sed для команды вставки

У меня есть куча php файлы, которые имеют много insert команды.

В каждом запросе я хочу вставить переменную столбца admin_id = '$admin_id',
то есть, если запрос

insert into users (ch_id, num_value) values ('2', '100')

запрос должен быть преобразован в

insert into users (admin_id, ch_id, num_value) values ($admin_id, '2', '100')

Для этого я выполнил следующую команду

sed -i 's/\(insert.*into.*\) (\(.*values\)/\1 (admin_id, \2/' *.php

а также

sed -i "s/\(insert.*into.*\) values (/\1 values ('\$admin_id', /" *.php

Вышеприведенное успешно сработало, но все еще сталкиваюсь с проблемой SQL-запросов, где нет where в запросе, т.е.

insert into abctable (id,no)

в

insert into tablename (admin_id, id, no)

а также

insert into abctable select $column from $tableperiod

в

insert into abctable select $column from $tableperiod where admin_id='$admin_id'

а также

insert into abctable select $column from $tableperiod where abc != 'xyz'

в

insert into abctable select $column from $tableperiod where admin_id = '$admin_id' and abc != 'xyz'

Как я могу вставить admin_id в этих запросах тоже?

Запросы в файлах php выполняются путем передачи запроса в функцию следующим образом:

execute_query("insert * from $table order by username");

Я могу найти запросы, которые еще могут быть изменены
проведение

grep 'execute_query' *| grep insert| grep -v admin_id  > stillleft.txt

3

Решение

Я решил это с помощью следующей команды

sed -e "s/\(query.*insert.*select.*where\)/& admin_id='\$admin_id' and /g"               -e t \
-e "s/\(query.*insert.*select.*\)\")/\1  where admin_id='\$admin_id\")'/g"           -e t \
-e "s/\(query.*insert.*\)(\(.*\)values (/\1(admin_id, \2values ('\$admin_id', /g"    -e t \
-e "s/\(query.*insert.*(\)/& admin_id, /g"  \
-i *.php
0

Другие решения

Я не уверен, что мои тесты правильны, но я думаю, что это может помочь вам:

Я изменил первое утверждение, потому что я думаю, что это проще, и оно соответствует первой и второй команде ВАШЕГО седа

sed -i 's/\(insert into .* (\)\(.*) values (\)\(.*\)) /\1admin_id, \2\$admin_id, \3/' *.php

Второй (первый, который вы ищете) должен работать со следующими

sed -i 's/\(insert into .* (\)\(.*) \)/\1admin_id, \2/' *.php

И последние два должны работать с этим:

sed -i "s/\(insert into \w* select \$column from \$tableperiod\)/\1 where admin_id='\$admin_id'/" *.php

Я надеюсь, что это работает для вас, если нет, пожалуйста, отправьте немного больше тестовых данных, если протестировали команды с текстом вашего вопроса в качестве ввода

0

Если вы используете несколько команд Sed, вы будете проходить полный файл каждый раз. Вы можете сделать это за один проход. Предполагая входной файл infile это выглядит так:

insert into users (ch_id, num_value) values ('2', '100')
insert into abctable (id, no)
insert into abctable select $column from $tableperiod
insert into abctable select $column from $tableperiod where abc != 'xyz'

мы можем использовать следующий скрипт Sed sedscr

/^insert into/ {
s/\(([^)]*)\)(.*)\(([^)]*)\)/(admin_id, \1)\2($admin_id, \3)/
s/^([^(]+)\(([^)]*)\)$/\1(admin_id, \2)/
/\(.*\)/! {
/where/s/$/ and admin_id ='$admin_id'/
/where/!s/$/ where admin_id='$admin_id'/
}
}

Это делает следующее:

  • если строка начинается с insert into, затем
    • для всех строк с двумя парами скобок вставить admin_id в первом и $admin_id во втором
    • для строк с одной парой скобок в конце вставьте admin_id
    • если нет скобок, то
      • если есть пункт «где», добавьте and admin_id = '$admin_id'
      • еще добавить where admin_id='$admin_id'

Это можно назвать следующим образом:

$ sed -rf sedscr infile
insert into users (admin_id, ch_id, num_value) values ($admin_id, '2', '100')
insert into abctable (admin_id, id, no)
insert into abctable select $column from $tableperiod where admin_id='$admin_id'
insert into abctable select $column from $tableperiod where abc != 'xyz' and admin_id ='$admin_id'

Если вы не можете использовать расширенные регулярные выражения (-r), кавычки в скобках должны быть обращены (все \( становиться ( и т. д.) и + должен быть заменен \{1,\},

Громоздкие регулярные выражения, такие как \(([^)]*)\) стоять «между буквальными скобками, захватывать ноль или более символов, которые не закрывающая круглая скобка «- это позволяет не жадный захват.

0
По вопросам рекламы [email protected]