SQLスタイルのBashの使用

ご挨拶! この短い記事は、Bashを使用してSQLスタイルのファイルを解析するいくつかの側面を明らかにすることを目的としています。 初心者にとっては興味深いでしょう。経験豊富なユーザーは、自分にとっても新しい何かを見つけるでしょう。

タスク構造:


期限切れのレポートを見つけることが必要です。

だから、Bashを見つけて、マン用に別のターミナルを開いて続行してください)

興味のある方は誰でも猫をお願いします。

プロジェクトを含むフォルダー形式の内部レポートシステム。 各プロジェクトのconfフォルダーには、レポートが作成されるテーブルに従って、 "schema"フィールドにHiveデータベースの名前を含むレポートを作成するための構成があります。 reportsフォルダー内-構成名を持つフォルダーに配置されたレポート自体。 各レポートは、 "table"オブジェクトの配列内のHiveテーブルに関する統計と、 "created_date"フィールドの作成日を含むjsonです。 ファイルの作成日ではなく、それを使用してみましょう。 レポートの作成後に変更されたテーブルを含むレポートを見つける必要があります。

なぜSQLスタイルなのですか? Bashは、SQLでのテーブルの処理を連想させる、列(通常はスペース)に分割されたテキストを操作する絶好の機会を提供します。

ツールキット:


始めましょう。 開始するには、使用するテーブルを曲げるだけです:

  grep -r "\"table\":" projects/*/reports/* | ... 

彼はこの形式でデータを提供します:
projects / project1 / reports / run1 / report1.json: "table": "table1"、
projects / project1 / reports / run2 / report2.json: "table": "table2"、
projects / project2 / reports / run3 / report3.json: "table": "table3"、
...
  ... | sed 's/:/ /g' | awk '{print $1 " " $3}' | sed 's/[\r\n",:]//g' | ... ... | sort -k 1b,1 | uniq > report_tables 

「:」をスペースに変更して、「テーブル」列からファイル名を正確に分離し、最初の(レポートファイル)および3番目(テーブル名)の列を印刷し、sed破片をきれいにし、最初のテーブルでreport_tablesを並べ替えて保存します。

次に、同じ方法で、report_datesテーブルを作成し、created_dateを使用して、もう少し列(日付と時刻)を表示します。

 grep -r "\"created_date\":" projects/*/reports/* | sed 's/:/ /g' | ... ... | awk '{print $1 " " $3"T"$4":"$5":"$6}' | sed 's/[\r\n",:]//g' | ... ... | sort -k 1b,1 | uniq > report_dates 

次に、レポートファイル名とテーブル名を1つの列に結合して結合します。レポートファイル、テーブル、およびこのレポートの作成日を含むテーブルを取得します。

 join report_tables report_dates | awk '{print $1"#"$2 " " $3}' | ... ... | sort -k 1b,1 > report_table_date 
projects / project1 / reports / run1 / report1.json#table1 2017-08-07T070918.024907
projects / project1 / reports / run1 / report1.json#table2 2017-08-07T070918.024907
projects / project1 / reports / run1 / report1.json#table3 2017-08-07T070918.024907
...

最初の部分は準備ができているようです。 今、類推により、使用されたデータベースを加熱します。

 grep -r "schema\":" projects/*/conf/* | sed 's/:/ /g' | ... ... | awk '{print $3 " " $1}' | sed 's/[\r\n":,]//g' | ... ... | sort -k 1b,1 | uniq > schema_configs 
schema1プロジェクト/ project1 / conf / run1.conf
schema1プロジェクト/ project1 / conf / run2.conf
schema2プロジェクト/ project2 / conf / run1.conf
...

これが最初の困難です。 前の表はレポートファイルに基づいており、これは構成ファイルに基づいています。 それらの間に貼り付ける必要があります:

 cat schema_configs | awk '{print $2}' | sort | uniq | ... 

考えてみてください。 xargs -n1 find ...置くだけxargs -n1 find ...設定自体の行が失われるため、できませんが、必要です。 したがって、サイクルを繰り返します。 まあ。 パイプを入れて行きます:
 ... | while read line; do <statements>; done | sort -k 1b,1 > config_reports 

次に、ステートメント内にすべてを記述します。
 dir=$(dirname $line); dir2=$(dirname $dir); ... run=$(echo $line | sed "s/.*\///" | sed 's/\.conf//g'); ... reps=$(find $dir2/reports/$run/ -name *.json); ... for r in $reps; do echo $line $r ; done 

複雑に見えます。 dirnameはファイルパスから最後のスラッシュへのパスを取得します。これを使用して、レポートファイルを数レベル($dir2)上に上げます。 次の式run=...は、ファイルrun.conf名前を$lineからrun.conf 、拡張子を切り捨てて起動構成の名前を取得します。 次に、 repsはこの構成のレポートを含むファイルの名前であり、それらのループにより、 $lineのファイルとレポート$rのファイルが表示されます。 config_reportsプレートを並べ替えて記述しconfig_reports
projects / project1 / conf / run1.conf projects / project1 / reports / run1 / report1.json
projects / project1 / conf / run1.conf projects / project1 / reports / run1 / report2.json
projects / project1 / conf / run2.conf projects / project1 / reports / run2 / report3.json
...

これは作業の最も重要な部分でした-構成のスペースとレポートのスペースを対応させること。 使用されたデータベースのテーブルの最終変更の日付を決定するためだけに残っており、必要なすべての情報があります。残りはすべてを適切に変更することです。 行こう:

 cat schema_configs | awk '{print $1}' | sort | uniq | ... ... |sed 's/^/path_in_hive/g' | sed 's/$/\.db/g' | ... ... | xargs -n1 -I dr hdfs dfs -ls dr | sed 's/\// /g' | ... ... | sed 's/\.db//g' | awk '{print $12 " " $13 " " $6"T"$7}' | ... ... | sort -k 1b,1 | uniq > schema_tables 

長さにもかかわらず、すべてが簡単です。 最初にschema_configsschema_configs 、そこから一意の回路をschema_configsし、 sed使用してHiveストレージへのパスを先頭に、 .db拡張子を末尾sed割り当てます。 そのような行ごとにhdfs dfs -lsを実行すると、指定されたデータベース内のすべてのテーブルとその最終変更日が表示されます。 すべてのスラッシュをスペースに変更し、データベースの名前、テーブルの名前、およびその変更の日付をschema_tables 、再ソートし、 schema_tablesプレートのschema_tablesschema_tables

最後のパート:

 # configs - tables join schema_configs schema_tables | awk '{print $2 " " $3 " " $4}' | ... ... | sort -k 1b,1 | uniq > config_tables # reports - tables hive dates join config_reports config_tables | awk '{print $2"#"$3 " " $4}' | ... ... | sort -k 1b,1 > report_table_hive_dates # final! join report_table_date report_table_hive_dates | sed 's/#/ /g' | ... ... | awk '{if ($3<$4) print $1}' | sort | uniq > outdated_reports 

最初に、 schema_configsschema_tablesをdbという名前のフィールドで結合すると、 config_tablesプレートが取得されますconfig_tables 、table、および最後に変更された日付です。 次に、 config_reportsconfig_tablesconfig_tablesして、最終的に一致するレポート(Hiveのテーブル)を取得します。 さらに、レポートを含むファイルの名前とテーブル名は、 #を使用して1つのフィールドに結合されます。 最後に、 report_table_datereport_table_hive_datesを結合し、ファイル名をレポートで、テーブル名をスペースで区切り、レポートの作成日がテーブルの変更日よりも小さいレポートを印刷し、一意のレポートを探して作業の準備をします。

おわりに


bashの9つのかなり単純な行は、この問題を解決するのに十分であることが判明しました。 次に、このスクリプトを王冠で実行すると、webmordは、 outdated_reports "Report is outdated"ファイルに焦点を合わせて、 "Report is outdated" outdated_reports見出しをoutdated_reportsできoutdated_reports (またはそうではありません)。

ここにコード

Source: https://habr.com/ru/post/J343758/


All Articles