製品の同級生に小さな問題を解決する.
9885 ワード
短い、平ら、速い.
背景
制品の学友は1つの店のshopIdリストをあげて、これらの店の最近の时间の同城の注文の数量を知りたいです.
shop.txt
既存のコマンドcurlがありますsearchは単一店舗の同城から注文書を受け取ることができます.
curl_searchの結果は以下の通りです.totalは同城からの注文数です.
得たい結果は、行ごとにshopId total
イニシアチブ
Shellの使用
まずスクリプトcurlを作成します.orders.sh:
次に、次の操作を行います.
Pythonの使用
Pythonスクリプトfetch_を作成totals.py
Python+Shellの使用
実際、Shellはタスク処理のコマンドフローを構築するのに適しており、Pythonは具体的な論理を処理するのに適している.両者を組み合わせて食べるともっといいです.まず単一店舗を扱うPythonスクリプトfetch_を作成total.py :
次に:
を選択して、
シナリオの選択
最初にPythonで解決しようと思った.しかしpythonはパラメータをつづり、curlを呼び出すスクリプトを書きます.ちょっと面倒です.次にデータプラットフォームに行ってhiveですくい取ろうとしたが、同城に注文書を送る標識はなかった.curl命令で単一店舗を手に入れることができる以上、ロットの問題を解決すればいいと思います.
ここには2つの問題があります.1.curlからsearchコマンドの結果からtotalが解析されます.2.curlコマンドを一括呼び出し、shopIdをパラメータとして渡す必要があります.
解析total
totalを解析し、sed+正規キャプチャ能力を使用します.
要領は、必要なものを()で囲み、引用で置き換えることです.例えば、私はtotalコロンの後ろの数字だけで、まず必要な部分
正規表現の基礎は「正規表現の基礎知識」を参照してください.
パラメトリックコールcurl
shopIdをcurlコマンドに渡す必要があります.ただしcurlコマンドのオプション-dのパラメータ
xargs
xargsは、ファイルを読み取り、各ローのデータをパラメータとして指定したコマンドに送信して実行できます.基本形式は:
ここでcurlを呼び出しtotalを解析してcurlと書くのはorders.shスクリプトファイルも、xargsコマンドをより簡潔にするためです.xargs-d[sep]は、セパレータsepを用いて入力を複数のデータに分割し、複数のデータをそれぞれ1つのパラメータとして指定コマンド処理に順次渡すものである.
コマンド置換
$(command):command自体をコマンドcommandの計算値で置き換え、コマンドの実行結果をパラメータとして他のコマンドに直接伝えることができます.
関連例:
パイプ本
Shellの最も強力な点は「接着」能力であり、任意の複数の小さなプログラムを組み合わせて一つのことを完成させることができる.パイプ|前のプログラムの出力を次のプログラムの入力に向け、2つの隣接するプログラムを接続する.パイプは接着能力を実現する強力なメカニズムである.
リダイレクト
>はリダイレクト記号で、コマンド実行結果をファイルにリダイレクトできます.コマンドの結果が非常に大きい場合に適用されます.
完全なコマンド
一般的には、簡単なコマンドをデバッグしてから統合します.
しかし、依然として難しすぎます.「curlコマンドにパラメータを入力」「コマンド置換」「文字エスケープ」などをすべて統合する必要があります.特に、curlコマンドにパラメータが入力されます.
完全なコマンドは次のとおりです.
なぜdの中でそんなに多くの転義をしたのか知りたいかもしれません.主にJavaサービス側が整形し、shellはデフォルトで伝達文字列に与えられる.このように多くの転義をしたのは、そのjsonパラメータ列をつづりながら店舗IDを整数として伝えるためだ.
1行まで手間を省いて書こうとしたが、1行を書くとエラーが発生しやすく、調査が難しく、複数のパラメータが入力される場合、拡張性が悪い.キーcurlコマンドのオプションパラメータには、単一引用符と二重引用符があり、コマンドも長いのでshell行に置いて、正しい文字列のつなぎ合わせを完了するのは難しいです.一行全体には向いていないようだ.こんな不必要な振り回しはしない.単一の二重引用符を持つ複雑な長いコマンドラインの接続は、スクリプトファイルに書くのが適切です.
に紹介される
使用サイクルは以下のとおりです.命名パラメータがあるとやはり伝わりやすい.
小結
この例では、Shellコマンドが一時的な小さなタスクに備えられる「短い、平らで速い」という特徴を示しています.しかし、複雑なコマンドを構築するには、Shellをよく知っておく必要があります.その中には、多くのものを統合する必要があります.特に文字列のエスケープやコマンドの伝達に関連する場合があります.そうしないと、かえって「速い」という利点が失われます.さらに、複雑なコマンドを単一のコマンドまたはスクリプトに分解することで、簡潔な統合コマンドを書きやすくすることが望ましい.
複雑なタスクスクリプトを構築するには、Pythonなど、自分のよく知っている言語を採用します.Pythonで実現し、curl結果を得た後、jsonモジュールで解析すればtotalを得ることができる.次にforループを書くと、バッチ呼び出しの問題を解決できます.
結論:pythonでスクリプトを書いて単一の記録を処理し、xargs-I{}python xxxを使用する.py{}でいいです.これには、直交相補的なpythonツールパッケージが必要です.Shellはタスク処理のコマンドフローを構築するのに適しており、Pythonは具体的な論理を処理するのに適している.両者を組み合わせて食べるともっといいです.
背景
制品の学友は1つの店のshopIdリストをあげて、これらの店の最近の时间の同城の注文の数量を知りたいです.
shop.txt
111,222,333
既存のコマンドcurlがありますsearchは単一店舗の同城から注文書を受け取ることができます.
curl -s -H "Content-Type: application/json" -X POST -d '{"source":"xxx", "requestId":"111", "searchParam": {"shopId": 111, "endTime":1583424000,"startTime":1580486400, "deliveryType":"local_delivery"}}' http://127.0.0.1:7001/app/order/search
curl_searchの結果は以下の通りです.totalは同城からの注文数です.
{"result":true,"code":0,"message":null,"data":{"success":true,"code":200,"message":"successful","data":{"orderNos":["202003051700001"],"total":22}}}
得たい結果は、行ごとにshopId total
111 22
222 256
333 1024
イニシアチブ
Shellの使用
まずスクリプトcurlを作成します.orders.sh:
#!/bin/sh
shopId=$1
curl -s -H "Content-Type: application/json" -X POST -d '{"source":"xxx", "requestId":"'"${shopId}"'", "searchParam": {"shopId":"'"${shopId}"'", "endTime":1583424000,"startTime":1580486400,"deliveryType":"local_delivery"}}' http://127.0.0.1:7001/app/order/search | echo $shopId $(sed -r 's/^.*total.*:([0-9]+)\}.*$/\1/')
次に、次の操作を行います.
cat /tmp/shop.txt | tr "," "
" | xargs -I {} sh curl_orders.sh {} > result.txt
Pythonの使用
Pythonスクリプトfetch_を作成totals.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import commands
import json
def fetchTotal(curl_cmd, success, fail):
(status, result) = commands.getstatusoutput(curl_cmd)
if status == 0:
return success(result)
return fail(result)
def success(result):
obj = json.loads(result)
if obj['result'] and obj['data']["success"]:
return obj['data']['data']['total']
return "Error"
def fail(result):
return "Error"
if __name__ == '__main__':
f = open('shop.txt')
for line in f:
shopIds = line.strip().split(',')
for shopId in shopIds:
cmd = """curl -s -H "Content-Type: application/json" -X POST -d '{"source":"xxx", "requestId":"""+ str(shopId) + """, "searchParam": {"shopId":""" + str(shopId) + """, "endTime":"1583424000","startTime":"1580486400", "deliveryType":"local_delivery", "exportedFieldNames":[]}}' http://127.0.0.1:7001/app/order/search"""
print shopId, " " , fetchTotal(cmd, success, fail)
Python+Shellの使用
実際、Shellはタスク処理のコマンドフローを構築するのに適しており、Pythonは具体的な論理を処理するのに適している.両者を組み合わせて食べるともっといいです.まず単一店舗を扱うPythonスクリプトfetch_を作成total.py :
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import commands
import json
import sys
def fetchTotal(curl_cmd, success, fail):
(status, result) = commands.getstatusoutput(curl_cmd)
if status == 0:
return success(result)
return fail(result)
def success(result):
obj = json.loads(result)
if obj['result'] and obj['data']["success"]:
return obj['data']['data']['total']
return "Error"
def fail(result):
return "Error"
def buildCmd(args):
shopId = args[1]
return """curl -s -H "Content-Type: application/json" -X POST -d '{"source":"xxx","requestId":"""+ str(shopId) + """, "searchParam": {"kdtId":""" + str(shopId) + """, "endTime":"1583424000","startTime":"1580486400", "deliveryType":"local_delivery"}}' http://127.0.0.1:7001/app/order/search"""
if __name__ == '__main__':
args = sys.argv
shopId = args[1]
print str(shopId), " " , fetchTotal(buildCmd(args), success, fail)
次に:
cat shop.txt | xargs -d "," -I {} python fetch_total.py {}
を使用します.を選択して、
シナリオの選択
最初にPythonで解決しようと思った.しかしpythonはパラメータをつづり、curlを呼び出すスクリプトを書きます.ちょっと面倒です.次にデータプラットフォームに行ってhiveですくい取ろうとしたが、同城に注文書を送る標識はなかった.curl命令で単一店舗を手に入れることができる以上、ロットの問題を解決すればいいと思います.
ここには2つの問題があります.1.curlからsearchコマンドの結果からtotalが解析されます.2.curlコマンドを一括呼び出し、shopIdをパラメータとして渡す必要があります.
解析total
totalを解析し、sed+正規キャプチャ能力を使用します.
要領は、必要なものを()で囲み、引用で置き換えることです.例えば、私はtotalコロンの後ろの数字だけで、まず必要な部分
([0-9]+)
を囲んで、それから左"total".*:
と右\}
を使って識別して、最後に引用記号$1で手に入れます.数値は、いくつ目(キャプチャされたグループ)のカッコを識別します.正規表現の基礎は「正規表現の基礎知識」を参照してください.
パラメトリックコールcurl
shopIdをcurlコマンドに渡す必要があります.ただしcurlコマンドのオプション-dのパラメータ
'{"shopId":"$shopId", "field2":"yyy"}'
には、二重引用符と単一引用符があります.これらは、指定した値に置き換えるのではなく、変数参照$shopIdを通常の文字列にします."'${shopId}'"
を使用してshopIdを入力できます.xargs
xargsは、ファイルを読み取り、各ローのデータをパラメータとして指定したコマンドに送信して実行できます.基本形式は:
cat file.txt | xargs -I {} Command {}
です.ファイルです.txtの各行のデータ.ここでcurlを呼び出しtotalを解析してcurlと書くのはorders.shスクリプトファイルも、xargsコマンドをより簡潔にするためです.xargs-d[sep]は、セパレータsepを用いて入力を複数のデータに分割し、複数のデータをそれぞれ1つのパラメータとして指定コマンド処理に順次渡すものである.
コマンド置換
$(command):command自体をコマンドcommandの計算値で置き換え、コマンドの実行結果をパラメータとして他のコマンドに直接伝えることができます.
関連例:
cat shop.txt | xargs -d "," -I {} echo $(echo \{\"source\":\"xxx\",\"requestId\":\"98765432\",\"searchParam\":\{\"shopId\":{},\"endTime\":1583424000,\"startTime\":1580486400,\"deliveryType\":\"local_delivery\"\}\})
curl -s http://127.0.0.1:7001/app/order/search -H "Content-Type: application/json" -X POST -d $(echo \{\"source\":\"xxx\",\"requestId\":\"98765432\",\"searchParam\":\{\"kdtId\":37,\"endTime\":1583424000,\"startTime\":1580486400,\"deliveryType\":\"local_delivery\"\}\})
パイプ本
Shellの最も強力な点は「接着」能力であり、任意の複数の小さなプログラムを組み合わせて一つのことを完成させることができる.パイプ|前のプログラムの出力を次のプログラムの入力に向け、2つの隣接するプログラムを接続する.パイプは接着能力を実現する強力なメカニズムである.
リダイレクト
>はリダイレクト記号で、コマンド実行結果をファイルにリダイレクトできます.コマンドの結果が非常に大きい場合に適用されます.
完全なコマンド
一般的には、簡単なコマンドをデバッグしてから統合します.
しかし、依然として難しすぎます.「curlコマンドにパラメータを入力」「コマンド置換」「文字エスケープ」などをすべて統合する必要があります.特に、curlコマンドにパラメータが入力されます.
完全なコマンドは次のとおりです.
sed 's/,/
/g' shop.txt | xargs -I {} sh -c 'echo {}" "$(curl -s -H "Content-Type: application/json" -X POST -d "{\"source\":\"xxx\", \"requestId\":\"123456879\", \"searchParam\": {\"shopId\":{},\"endTime\":1583424000,\"startTime\":1580486400, \"deliveryType\":\"local_delivery\"}}" http://127.0.0.1:7001/app/order/search | sed -r "s/^.*total.*:([0-9]+)\}.*$/\1/")'
sed 's/,/
/g' shop.txt | xargs -I {} sh -c 'total=$(curl -s -H "Content-Type: application/json" -X POST -d "{\"source\":\"xxx\",\"requestId\":\"123456879\", \"searchParam\": {\"shopId\":{},\"endTime\":1583424000,\"startTime\":1580486400, \"deliveryTypeDesc\":\"local_delivery\"}}" http://127.0.0.1:7001/app/order/search | sed -r "s/^.*total.*:([0-9]+)\}.*$/\1/");echo {} $total'
なぜdの中でそんなに多くの転義をしたのか知りたいかもしれません.主にJavaサービス側が整形し、shellはデフォルトで伝達文字列に与えられる.このように多くの転義をしたのは、そのjsonパラメータ列をつづりながら店舗IDを整数として伝えるためだ.
1行まで手間を省いて書こうとしたが、1行を書くとエラーが発生しやすく、調査が難しく、複数のパラメータが入力される場合、拡張性が悪い.キーcurlコマンドのオプションパラメータには、単一引用符と二重引用符があり、コマンドも長いのでshell行に置いて、正しい文字列のつなぎ合わせを完了するのは難しいです.一行全体には向いていないようだ.こんな不必要な振り回しはしない.単一の二重引用符を持つ複雑な長いコマンドラインの接続は、スクリプトファイルに書くのが適切です.
に紹介される
使用サイクルは以下のとおりです.命名パラメータがあるとやはり伝わりやすい.
for shopId in $(sed 's/,/
/g' shop.txt); do echo $shopId $(curl -s -H "Content-Type: application/json" -X POST -d '{"source":"xxx", "requestId":"$shopId", "searchParam": {"shopId":"'$shopId'", "endTime":"1583424000","startTime":"1580486400", "deliveryType":"local_delivery"}}' http://127.0.0.1:7001/app/order/search | sed -r 's/^.*total.*:([0-9]+)\}.*$/\1/'); done
sed 's/,/
/g' shop.txt | while read line; do echo $line $(curl -s -H "Content-Type: application/json" -X POST -d '{"source":"xxx","requestId":"$line", "searchParam": {"shopId":"'$line'", "endTime":"1583424000","startTime":"1580486400", "deliveryType":"local_delivery"}}' http://127.0.0.1:7001/app/order/search | sed -r 's/^.*total.*:([0-9]+)\}.*$/\1/'); done
小結
この例では、Shellコマンドが一時的な小さなタスクに備えられる「短い、平らで速い」という特徴を示しています.しかし、複雑なコマンドを構築するには、Shellをよく知っておく必要があります.その中には、多くのものを統合する必要があります.特に文字列のエスケープやコマンドの伝達に関連する場合があります.そうしないと、かえって「速い」という利点が失われます.さらに、複雑なコマンドを単一のコマンドまたはスクリプトに分解することで、簡潔な統合コマンドを書きやすくすることが望ましい.
複雑なタスクスクリプトを構築するには、Pythonなど、自分のよく知っている言語を採用します.Pythonで実現し、curl結果を得た後、jsonモジュールで解析すればtotalを得ることができる.次にforループを書くと、バッチ呼び出しの問題を解決できます.
結論:pythonでスクリプトを書いて単一の記録を処理し、xargs-I{}python xxxを使用する.py{}でいいです.これには、直交相補的なpythonツールパッケージが必要です.Shellはタスク処理のコマンドフローを構築するのに適しており、Pythonは具体的な論理を処理するのに適している.両者を組み合わせて食べるともっといいです.