web-dev-qa-db-ja.com

コマンドの出力から2つの値を抽出します

スクリプトで次のコマンドを使用して、合成Wi-Fi情報を取得しています。

echo "$(
    iw dev wlp1s0 link |
    grep '^\s*SSID:\s' |
    sed -r 's/^\s*SSID:\s//'
) $(
    iw dev wlp1s0 link |
    grep '^\s*signal:\s' |
    sed -r 's/^\s*signal:\s//'
)"

それは機能し、出力は次のようになります。

MySSID -46 dBm

ただし、結果が同じになることがわかっているときに、iw dev wlp1s0 linkに同じ呼び出しを2回行うのはばかげていると感じます。また、iwからの出力を一時変数に格納する必要がないようにしたいと思います。

teeを使用して、iwからの出力を2つのジョブに「複製」し、結果を連結するためにできることはありますか?

2
fonini

一時変数を使用しても問題はありません。変数は、複数回使用されるデータを格納するために作成されます。

この場合、2つのgrep/sed呼び出しを1つの呼び出しに組み合わせてGNU grep、sed、またはawkにすることができます。sedを使用すると簡単です。-nオプションを出力のみに渡します。明示的に印刷された行、および置換が行われた行を印刷します。

echo "$(
    iw dev wlp1s0 link |
    sed -nr -e 's/^\s*SSID:\s//p' -e 's/^\s*signal:\s//'
)"

元のスクリプトとの違いが1つあります。それは、SSIDと信号の値がiwの出力に表示される順序で出力されることです。その順序から独立したい場合は、sedを使用するのは面倒なので、awkが最適なツールになります。このアプローチを使用すると、1行で出力を取得するのも同じくらい簡単です。次のスクリプトは、各設定の最後の値を出力します(iwは1つしか出力しないため、この特定のケースでは問題ありません)。変更例: ssid = $0からssid = ssid " " $0まで、すべてを印刷します。

iw dev wlp1s0 link | awk '
    $1=="SSID:" {sub(/[^:]*:[[:space:]]*/,""); ssid = $0}
    $1=="signal:" {sub(/[^:]*:[[:space:]]*/,""); signal = $0}
    END {print ssid, signal}
'

一般に、コマンドの出力を2つの異なるフィルターに送信する場合は、teeを使用して、 プロセス置換 を渡すことができます。これは、パイプを一般化するbash機能(ksh93から、zshにも存在しますが、プレーンshには存在しません)です。 teeコマンドは、指定されたコマンドに接続されているパイプを指定するファイル名を参照します。

iw dev wlp1s0 link | tee >(
    grep '^\s*SSID:\s' |
    sed -r 's/^\s*SSID:\s//'
  ) |
    grep '^\s*signal:\s' |
    sed -r 's/^\s*signal:\s//'

このアプローチの制限は、プロセス置換のコマンドがそれ自体のサブシェルで実行されることです。変数を取得したり、出力を他のユーザーに分散させる方法を制御したりすることはできません。

これは、あなたと同じ出力を持つiwコマンドの1つのライナーです。

iw dev wlp1s0 link | grep 'SSID:\|signal' | awk '{printf "%s ", $2$3}'

私の出力:

ZyXEL-AP-2,4GHz -46dBm
1
krt

そんな感じ ?

_iw dev wlp1s0 link |
grep -E '^\s*(SSID|signal):\s' |
sed -r 's/^\s*(SSID|signal):\s//' |
awk '{printf $0}'
_

grepは_(SSID|signal):_を受け入れるため、_SSID:_と_signal:_の両方に一致します。

_-E_はオプションですが、使用しない場合は、特別な意味の文字をエスケープすることを検討してください。ここでは、\(SSID\|signal\):になります

同じ正規表現をsed部分に使用できます。

最後に、awkを使用して、末尾の改行をすべて削除します(それ以外の場合、出力は2行で表示されます)。

0
apaul