Sed

帶有 AND/OR/NOT 的複雜 sed 命令

  • January 7, 2016

我有一堆php包含許多select命令的文件。

在每個查詢中,我想插入一個列變數admin_id = '$admin_id' ,即如果查詢是select * from users where abc='xyz' and qwe='fgh'查詢應該轉換為select * from users where admin_id = '$admin_id' and abc='xyz' and qwe='fgh'.

為此,我執行了以下命令sed -i "s/\(\"select.*\)where /\1 where admin_id = '\$admin_id' and /" *.php

以上已成功執行,但仍然面臨查詢中沒有 SQL 查詢的問題,whereselect * from users. 我如何也可以插入admin_id = '$admin_id'這些查詢?

通過以下方式將查詢傳遞給函式來執行 php 文件中的查詢: execute_query("select * from $table order by username");

緊握

我可以通過執行找到仍然需要修改的查詢:grep 'execute_query' *| grep select| grep -v admin_id > stillleft.txt

如果你堅持使用 sed,你可以使用兩個連續s的命令。為避免第二個在同一行的第一個之後執行,請t在其間添加一個命令;如果前面的s命令進行了替換,這將跳過所有剩餘的命令。

sed -e "s/\"select[^\";]* where /&admin_id = '\$admin_id' and /" -e t \
   -e "s/\"select[^\"]*/& where admin_id = '\$admin_id' /" \
   -i  *.php

請注意,這並不健壯:它無法處理select欄位選擇跨越多行的子句,它無法處理在同一行上沒有where但例如 a的查詢,如果 agroup by查詢包含where作為子字元串等。檢查輸入和輸出以確保您沒有遇到任何有問題的情況。

使用 perl,您可以使用非貪婪重複運算符在第一個保留字或查詢結尾處停止匹配。這仍然是近似的,但更穩健一些。Perl 還允許替換是構造替換字元串的任意表達式(替換e後帶有後綴),因此我們可以在那裡放置一個條件。

perl -i -p -e '
   s[("select.*?)(\b(?:where|group|having|order|limit|procedure|into|for|lock)\b|[;"]|$)]
    [$1 . " where admin_id = '\$admin_id' " . ($2 eq "where" ? "and" : $2)]e
' *.php

PS"…'$admin_id'…"看起來像是等待發生的 SQL 注入,除非$admin_id不能包含'(而且我認為格式錯誤的 UTF-8 也可能有問題)。

引用自:https://unix.stackexchange.com/questions/253660