AND/OR/NOTを使用した複雑なsedコマンド

AND/OR/NOTを使用した複雑なsedコマンド

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

where上記の方法は正常に実行されたがクエリにはIEがないSQLクエリの問題にまだ直面していますselect * from users。これらのクエリをどのように挿入できますかadmin_id = '$admin_id'

PHPファイルのクエリは、次の方法でクエリを関数に渡すことによって実行されます。 execute_query("select * from $table order by username");

grep

以下を実行して、変更が必要なクエリを見つけることができます。grep 'execute_query' *| grep select| grep -v admin_id > stillleft.txt

答え1

sedの使用に固執する場合は、2つのsコマンドを連続して使用できます。同じ行で最初のコマンドの後に2番目のコマンドを実行したくない場合は、それらの間にコマンドを追加して、前のコマンドが置き換えられた場合は、残りの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がないクエリは処理できません。入力と出力を確認して、問題が発生していないことを確認してください。group bywhere

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インジェクションが発生するのを待っているようです(そして、誤った形式のUTF-8も問題かもしれません)。$admin_id'

答え2

admin_id = '$admin_id' and存在する場合は後usersでのみ追加したい場合は、where次のことができます。

sed "s/\(select.*\)users[ ]*\(where\)\{0,1\}/\1 users where admin_id = '\$admin_id' and /" *.php

-i期待した結果が出たらフラグを立ててください。

その\(where\)\{0,1\}部分は正規表現をまねるためのトリックです?。つまり、0~1番を貪欲に繰り返すという意味です。

関連情報