2017-01-05 6 views
0

ここでは初心者の方は、私が使っている混乱している言葉を許してください。 私が持っている共通のタスクは、名前のリストを取得し、テーブル内の名前を見て、それらが私たちのサイトに "生きている"かどうかを確認するMySQLクエリを実行することです。初心者:入れ子式のif文、ループの結果、SQLの結果

これを一度に1つずつ実行すると、私のSQLクエリが正常に動作します。私は、複数の名前をリストしたファイルからループを使ってクエリを実行したかったのです。これもうまく動作します。

私はすぐにこれを入力して作業を行うことができるように私は私のbashプロファイルにこのクエリループを追加しました:これは正常に動作します

$ ValidOnSite fileName 

を、そして私もの自分を思い出させるために私のプロセスの使用法ステートメントを追加しました構文

nameA 
nameB 

私はその後、入力します:

validOnSite list.txt 

と両方のエントリ内のファイルが含ま "list.txtに" を使用して

validOnSite() { 


     if [[ "$1" == "" ]] || [[ "$1" == "-h" ]] || [[ "$1" == "--help" ]]; then 
       echo "Usage:" 
       echo " $ validOnSite [filename]" 
       echo " Where validOnSite uses specified file as variables in sql query:" 
       echo " SELECT name, active FROM dbDb WHERE name=lines in file" 
     else 

       cat $1 | while read line ; do hgsql -h genome-centdb hgcentral -Ne "select name, active from dbDb where name='$line'" ; done 

       fi 

:以下は、私はそれが正常に動作しなければならないものですlist.txtは自分のクエリ基準を満たしており、sqlにあります。結果は次のようになります。

nameA 1 
nameB 1 

各結果の後に "1"が表示されます。私はこれが何らかの「はい」のステータスだと考えています。

ここで、私はlist.txtに3番目の名前を追加します.1つは、sqlで一致しないことがわかっています。今list.txtに含まれています

nameA 
nameB 
foo 

私は再び3行で私のリストについては、このコマンドを実行すると:

validOnSiteを

私の結果は、私が第一のバージョンを使用する場合と同じですLIST.TXT file.txtとの、そして私は、私はまだ行だけが成功したかを確認、行が失敗したかを確認することはできません。

nameA 1 
nameB 1 

私はif文のネストされたを追加するためにあらゆる種類のものをしようとしている、その何かを"$行が一致すれば、"エコー "合格"、そうでなければ "失敗"となる。

私の結果に「1」は見たくない。緑と

nameA pass 
nameB pass 
foo fail 

またはより良い、カラーコードパスをし、赤で失敗:2試合と1の不一致とfile.txtを使用して、私は私の結果はようにしたいと思います。

私はここで初心者、言ったように...右方向に:)

任意のポインタが役立つだろう。ここに私の最新の悲しい試みですが、私は完全に間違った方向に行くことも実現:

validOnSite() { 


     if [[ "$1" == "" ]] || [[ "$1" == "-h" ]] || [[ "$1" == "--help" ]]; then 
       echo "Usage:" 
       echo " $ validOnSite [filename]" 
       echo " Where validOnSite uses specified file as variables in sql query:" 
       echo " SELECT name, active FROM dbDb WHERE name=lines in file" 
     else 

       cat $1 | while read line ; do hgsql -h genome-centdb hgcentral -Ne "select name, active from dbDb where name='$line'" > /dev/null ; done 
if ("status") then 
     echo $line "failed" 
     echo $line "failed" >> outfile 
else 
    echo $line "ok" 
    echo $line "ok" >>outfile 
    clear 
    cat outfile 
    fi 
fi 

何かが私の最後の試みでクレイジーに見える場合、それはされているので、それはだ - 私はちょうど周りグーグルとできるだけ多くをしようとしています私が学ぶことができるように物事を学ぶ。何か助けていただければ幸いですが、長いことこの作業に取り掛かってしまったと思いますが、私は前進して解決策を見つけることに興奮しています!私はstdoutを理解することについて私が欠けているものがあると思います。

注:私はアウトファイルは必要ありませんが、目標を達成するために必要な場合は問題ありません。標準的な結果だけで十分であり、好ましい。

注:hgssqlはMySQLサーバーの名前です。 MySQLの部分はうまく動作し、私はbashの出力を処理するためのより良い方法を探しています。私はstderrについて私が紛失しているものがあると思います。私は初心者ですから、私はかなり簡単な答えを探しています!

+0

私はhgsql' 'に慣れていないんだけど、私は疑います'foo'のエラーは' stdout'の代わりに 'stderr'に書き出されます)、 'stdout'の単純なリダイレクションでファイルにリダイレクトされることはありません。もう一つの考えは、 'hgsql'は、失敗したクエリの結果を報告するために追加のオプション(例えば、' --verbose'などを推測する)を必要とするかもしれないということです。 'hgsql'文書を参考にして、これらの行に役立つものが見つかったら参照してください。 –

+0

コメントありがとうございます。実際、hgsqlはMySQLサーバの名前に過ぎません。 – Cath

+1

なぜ 'mysql -Bse 'query ..." '-B'(* batch *)モードを使うと、各クエリの結果が返されます。 –

答えて

0

私は、hgsqlによって、あなたはMySQLクエリを実行できるいくつかのMercurial拡張を意味すると思います。私はhgsqlがどのように動作するのか分かりませんが、MySQLは一致する行だけを返します。しかし、シェル・スクリプティングの場合、一致した行の数がゼロであっても余分な情報を含む可能性がある文字列が結果になります。たとえば、一部のMySQLクライアントでは、ヘッダーや "No rows found"のような文字列が返される可能性があります。

公式mysqlクライアントでどのように処理されるかを示します。 hgsqlを次の例のドキュメントを参考にして調整することができます。

if [ -t 1 ]; then 
    red_color=$(tput setaf 1) 
    green_color=$(tput setaf 2) 
    reset_color=$(tput sgr0) 
else 
    red_color= 
    green_color= 
    reset_color= 
fi 


colorize_flag() { 
    local color 

    if [ "$1" = 'fail' ]; then 
    color="$red_color" 
    else 
    color="$green_color" 
    fi 

    printf '%s' "${color}${1}${reset_color}" 
} 


sql_fmt='SELECT IF(active, "pass", "fail") AS flag FROM dbDb WHERE name = "%s"' 

while IFS= read -r line; do 
    sql=$(printf "$sql_fmt" "$line") 

    flag=$(mysql --skip-column-names dbname -e "$sql") 
    [ -z "$flag" ] && flag='fail' 

    printf '%-20s%s\n' "$line" "$(colorize_flag "$flag")" 
done < file 

スクリプトは、インタラクティブモードで実行されている場合は、最初のブロックは、(help testを参照してください)ファイルディスクリプタ1(標準出力)は、端末上で開かれているか否かをチェックすることによって検出しました。スクリプトがターミナルで開かれている場合、スクリプトは対話的に実行されているとみなします。つまり、標準出力はユーザーの端末に直接接続されますが、パイプ経由ではありません。対話型モードでは、tputコマンドの助けを借りて、ターミナルカラーコードに変数を割り当てます。

colorize_flag関数は文字列($1)を受け入れ、その値に応じて適用されたカラーコードで文字列を出力します。

最後のブロックは、行ごとにfileと表示されます。各行に対して、SQL照会ストリング(sql)が作成され、mysqlコマンドが呼び出され、列名が出力から取り除かれます。 mysqlコマンドの出力は、コマンド置換によってflagに割り当てられます。 "$flag"が空の場合、'fail'に割り当てられます。 $lineと色付きフラグは標準出力に出力されます。


あなたは例えば、パイプを介して出力を連鎖によって、非対話型モードをテストすることができます。

./script | tee -a 

私はにシェル変数を渡すために、一般的に悪い考えであることを警告しなければなりません値が適切にエスケープされていない限り、SQLクエリ。普及しているシェルはMySQLの文字列をエスケープするツールを提供していません。したがって、Perl、PHP、またはクエリを安全に構築して実行できるプログラミング言語でクエリを実行することを検討してください。

パフォーマンス面では、単一のクエリを実行し、ループ内で複数のクエリを実行するのではなく、ループ内で結果セットを解析する方が便利です(ただし、prepared statementsは例外です)。

+0

ありがとうございました。私はあなたの時間を非常に感謝します!私はあなたのコードをSQLクエリの直後に貼り付けようとしました(cat $ 1 |行の読み込み中など...)。しかし、それはうまくいきませんでした。私はこれが私の理解を超えているかもしれないと思うし、おそらくもっと簡単な解決策がありますか? – Cath

+0

@Cath、コードをどこかに貼り付けることができますか?実際に私はあなたの 'hgsql'を使ってコード内の' mysql'コマンドを置き換えるだけだと考えました –

0

私が知っているいくつかの基本的なことをまとめて解決する方法を見つけました。エレガントではありませんが、今は十分に機能しています。私は、「1」を切り取って、新しいファイルを作っ

nameA 1 
nameB 1 

:私は、ファイル出力の「[ファイル名]の結果を」作成しました。私はfile.txtにどの行が存在するのかを調べるために "[fileName] results"とlist.txtを比較しましたが、結果には存在しません。

注:私の.zshrcファイルには次のものがあります。

validOnSite() { 


     if [[ "$1" == "" ]] || [[ "$1" == "-h" ]] || [[ "$1" == "--help" ]]; then 
       echo "Usage:" 
       echo " $ validOnSite [filename]" 
       echo " Where validOnSite uses specified file as variables in sql query:" 
       echo " SELECT name, active FROM dbDb WHERE name=lines in file" 
     else 

     cat $1 | while read line ; do hgsql -h genome-centdb hgcentral -Ne "select name from dbDb where name='$line' and active='1'" >> $1"Pass"; done 

autoload -U colors 
colors 
echo $fg_bold[magenta]Assemblies active on site${reset_color} 
echo 
cat $1"Pass" 
echo 
echo $fg_bold[red]Not active or not found on site${reset_color} 
comm -23 $1 $1"Pass" 2> /dev/null 
echo 
echo 

mv $1"Pass" ~cath/myFiles/validOnSiteResults 
echo "Results file containing only active assemblies resides in ~cath/myFiles/validOnSiteResults" 

fi 
} 

list.txtに:

nameA 
nameB 
foo 

マイ入力:

validOnSite list.txt 

マイ出力:

Assemblies active on site (<--this font is magenta) 

nameA 
nameB 

Not active or not found on site (<--this font is red) 
foo 


Results file containing only active assemblies resides in ~me/myFiles/validOnRRresults