【问题标题】:Complex sed Command for Insert Command插入命令的复杂 sed 命令
【发布时间】:2016-01-19 19:33:11
【问题描述】:

我有一堆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

上述方法已成功运行,但仍然面临查询中没有where 的SQL 查询问题,即

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

【问题讨论】:

标签: sed grep regex php


【解决方案1】:

我已经用下面的命令解决了

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

【讨论】:

    【解决方案2】:

    我不确定我的测试用例是否正确,但我认为这可以帮助您:

    我更改了第一个语句,因为我认为它更容易,并且它匹配您的 sed 的第一个和第二个命令

    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
    

    我希望这对你有用,如果没有,请发送更多测试数据,如果以你的问题文本作为输入测试命令

    【讨论】:

      【解决方案3】:

      如果您使用多个 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
        • 如果没有括号,则
          • 如果有“where”子句,追加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),则必须反转括号的引用(所有 \( 变为 ( 等)并且必须将 + 替换为 @987654336 @。

      诸如\(([^)]*)\) 之类的繁琐正则表达式代表“在文字括号之间,捕获零个或多个不是右括号的字符”——这可以实现非贪婪捕获。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-07-06
        • 2014-10-27
        • 2018-01-08
        • 2019-01-03
        • 1970-01-01
        • 2018-07-08
        • 1970-01-01
        相关资源
        最近更新 更多