web-dev-qa-db-ja.com

Bashスクリプト-変数に `curl`出力を保存し、変数の文字列に対してフォーマットします

curlデータをシェルスクリプト変数に入れてから、catまたはawkを使用して、その変数をファイルであるかのように操作したいと思っていました。

これは可能ですか、または回避策はありますか? curlコマンドをファイルに保存する必要がありますか?

curlを何回か実行する必要がありますか?

私はcurling ipinfo.ioで、 "city"と "region"に一致する行を出力したいです。 awkおよびsedを使用して、出力を必要に応じてフォーマットする方法を知っています。

たとえば、Google DNS IPアドレスの結果としてcurl ipinfo.io/"8.8.8.8"を試してください。

「Mountain View」と「California」だけを、できれば同じ行に、「Mountain View、California」などの一般的な書式で印刷したいと思います。

7
cfye14

一般に、JSONオブジェクトを解析するより適切な方法がありますが、この場合、JSONオブジェクトは非常に単純なので、curlの出力を変数に格納し(可能な場合)、AWKを使用するだけです。

var="$(curl ipinfo.io/"8.8.8.8" 2>/dev/null)"
<<<"$var" awk -F'"' '$2=="city"{printf("%s, ", $4)}$2=="region"{print $4}'
% var="$(curl ipinfo.io/"8.8.8.8" 2>/dev/null)"
% <<<"$var" awk -F'"' '$2=="city"{printf("%s, ", $4)}$2=="region"{print $4}'
Mountain View, California

ただし、curlの出力を複数回使用する場合を除き、パイプを使用できます。

curl ipinfo.io/"8.8.8.8" 2>/dev/null | awk -F'"' '$2=="city"{printf("%s, ", $4)}$2=="region"{print $4}'
curl ipinfo.io/"8.8.8.8" 2>/dev/null | awk -F'"' '$2=="city"{printf("%s, ", $4)}$2=="region"{print $4}'
Mountain View, California

<<<は、「here string」と呼ばれる入力リダイレクトの形式です。コマンドのSTDINを端末から文字列にリダイレクトします。

ここで起こることは、$varが二重引用符の間で展開されることです。 AWKコマンドのSTDINは端末から展開された文字列にリダイレクトされ、結果としてAWKは文字列を入力ファイルとして読み取ります。

8
kos

データをシェルスクリプト変数にカールし、catまたはawkを使用してその変数をファイルのように操作したいと思っていました。これは可能ですか、または回避策はありますか?

もちろんできます。コンテンツが大きすぎない場合、およびコンテンツを解析するために複数のコマンドを実行する場合は、毎回再ダウンロードするのではなく、メモリにキャッシュすることをお勧めします。

curlの結果を変数に保存するには:

ipinfo=$(curl ipinfo.io/8.8.8.8)

コマンドを実行するには:

<<< "$ipinfo" awk ...
<<< "$ipinfo" sed ...

二重引用符「 `$ ipinfo」は、すべての空白文字を保持するために重要です。

変数にコンテンツを保存しない「回避策」は、 @ kos のように、単一のパイプラインでコンテンツを処理する方法を見つけることです。

6
janos

これを行う簡単で読みやすい別の方法として、すべてのLinuxベースのシステムに存在するpythonを使用して、jsonを解析できます。

単に、jsonおよびsysパッケージをインポートしてjsonオブジェクトをロードし、resultオブジェクトから必要なプロパティを印刷します。

curl ipinfo.io/"8.8.8.8" 2>/dev/null | 
  python -c 'import  json,sys; 
             result=json.load(sys.stdin); 
             print(result["'city'"] + ", " + result["'region'"])';

より読みやすい方法でスクリプトを追加しましたが、複数行で記述する必要がある場合は、1行に入力するか、各行の最後に\を追加する必要があります。

1