Stdout(command1 -p=aaa -v=bbb -i=4
)にデータを出力するコマンドがあります。出力行には次の値を含めることができます。
rate (10%) - name: value - 10Kbps
その「レート」を保存するために、その出力をgrepしたいと思います(ここではパイプが役立つと思います)。そして最後に、そのレートを2番目のコマンドのパラメーターの値にしたいとします(command2 -t=${rate}
としましょう)。
それは私の側でトリッキーに見えます。パイプ、grep、sedなどの使い方をもっと知りたいのですが。
私はそのような多くの組み合わせを試しましたが、私はこれらについて混乱しています:
$ command1 -p=aaa -v=bbb -i=4 | grep "rate" 2>&1 command2 -t="rate was "${rate}
2つの非常に異なるタイプの入力を混乱させています。
stdin
)これらは異なり、さまざまな目的に役立ちます。一部のコマンドは、両方の方法で入力を受け取ることができますが、通常はそれらを別々に使用します。 wc
コマンドを例にとります:
stdin
による入力の受け渡し:
_ls | wc -l
_
これは、ls
の出力の行をカウントします
コマンドライン引数で入力を渡す:
_wc -l $(ls)
_
これは行数をカウントしますファイルのリスト内ls
によって出力されます
全く違うもの。
あなたの質問に答えるには、最初のコマンドの出力からレートをキャプチャし、そのレートを2番目のコマンドのコマンドライン引数として使用したいようです。これを行う1つの方法を次に示します。
_rate=$(command1 | sed -ne 's/^rate..\([0-9]*\)%.*/\1/p')
command2 -t "rate was $rate"
_
sed
の説明:
s/pattern/replacement/
_コマンドは、いくつかのパターンを置き換えることです^rate
_)で始まり、その後に任意の2文字(_..
_)が続き、その後に0個以上の数字が続き、その後に_%
_が続き、残りのテキスト(_.*
_)\1
_は、\(...\)
内にキャプチャされた最初の式の内容を意味するため、この場合は_%
_記号の前の数字sed
コマンドの_-n
_フラグは、デフォルトでは行を印刷しないことを意味します。 _s///
_コマンドの最後のp
は、置換があった場合に行を出力することを意味します。つまり、コマンドは一致があった場合にのみ何かを出力します。私はこれを使う傾向があります:
command1 | xargs -I{} command2 {}
command1
の出力を、置換(中括弧)を使用してxargsからcommand2
に渡します。 command1がfind
の場合、必ず-print0
を使用し、xargs
に-0
を追加してnullで終了する文字列にすると、xargs
がcommand2
を呼び出します見つかったものごとに。
あなたの場合(そして@Janosからsedラインを取る):
command1 -p=aaa -v=bbb -i=4 | sed -ne 's/^rate..\([0-9]*\)%.*/\1/p' | xargs -I{} command2 -t="rate was {}"
_command1
_の出力をシミュレートするには、次のエコーステートメントを使用しています。
_$ echo -e "Foo\nrate (10%) - name: value - 10Kbps\nBar"
$ alias command1='echo -e "Blah\nrate (10%) - name: value - 10Kbps\nBlag"'
_
簡単なテスト:
_$ command1
Blah
rate (10%) - name: value - 10Kbps
Blag
_
それはすべて良いので、解析してみましょう。
_$ command1 | grep 'rate'
rate (10%) - name: value - 10Kbps
_
したがって、必要な行を_command1
_から取得し、それを_command2
_に渡します。
_$ alias command2='echo'
$ command2 -t="rate was "$(command1 | grep 'rate')
-t=rate was rate (10%) - name: value - 10Kbps
_
"rate was "$(command1 | grep 'rate')
が自動的に連結されることを期待しています。空白のためにそれが機能しない場合は、代わりにそのように入力を渡すことができるはずです:
_$ alias command2='echo'
$ command2 -t=$(echo '"rate was ' $(command1 | grep 'rate') '"')
-t="rate was rate (10%) - name: value - 10Kbps "
_
最初のタスクは、そのラインからレートを抽出することです。 GNU grep(非組み込みLinuxまたはCygwin)の場合、_-o
_オプションを使用できます。必要な部分は、数字のみを含み、その後に_%
_記号。_%
_自体を抽出しない場合は、追加のトリックが必要です:a zero-width lookahead assertion 、これは何にも一致しませんが、何も従わない場合のみ_%
_による。
_command1 -p=aaa -v=bbb -i=4 | grep -o -P '[0-9]+(?=%)'
_
別の可能性は、sedを使用することです。 sedの行の一部を抽出するには、s
コマンドを使用して、行全体(_^
_で始まり__$
_で終わる)に一致する正規表現を、グループに保持する(\(…\)
)。保持するグループの内容で行全体を置き換えます。一般に、_-n
_オプションを渡してデフォルトの印刷をオフにし、p
修飾子を入れて、抽出するものがある行を印刷します(ここでは1行なので問題ではありません)。より多くのsedトリックについては、 一致するパターンの後の行の部分のみを返す および 「sed」に一致する正規表現を抽出して、周囲の文字を印刷せずに を参照してください。
_command1 -p=aaa -v=bbb -i=4 | sed 's/^.*rate(\([0-9]*\)%).*$/\1/'
_
Sedよりも柔軟性が高く、awkです。 Awkは小さな命令型言語で各行の命令を実行します。ここでレートを抽出する方法はたくさんあります。 2番目のフィールドを選択し(フィールドはデフォルトで空白で区切られています)、数字以外のすべての文字を削除します。
_command1 -p=aaa -v=bbb -i=4 | awk '{gsub(/[^0-9]+/, "", $2); print $2}'
_
次のステップは、レートを抽出したので、それを_command2
_への引数として渡すことです。そのためのツールは command susbtitution です。 $(…)
(ドル括弧)内にコマンドを配置すると、その出力がコマンドラインに代入されます。コマンドの出力は、空白スペースブロックごとに個別の単語に分割され、各単語はワイルドカードパターンとして扱われます。これを実行したくない場合は、コマンド置換を二重引用符で囲んでください:"$(…)"
。二重引用符を使用すると、コマンドの出力が単一のパラメーターとして直接使用されます(唯一の変換は、出力の最後の改行が削除されることです)。
_command2 -t "$(command1 -p=aaa -v=bbb -i=4 |
sed 's/^.*rate(\([0-9]*\)%).*$/\1/')"
_
通常、 `command`を使用して、出力を別のコマンドの引数として配置します。たとえば、freebsdでプロセスfooによって消費されたリソースを見つけるには、次のようになります。
procstat -r `pgrep -x foo`
ここで、pgrepは、プロセスのPIDを引数として期待するprocstatコマンドに渡されるプロセスfooのPIDを抽出するために使用されます。
grep
を使用できます。これはPCRE-Perl互換の正規表現です。これにより、後読みを使用して、grepするときに結果に文字列「rate」を含めずに、rateの値に一致させることができます。
_$ echo "rate (10%) - name: value - 10Kbps" | grep -oP '(?<=^rate \()\d+'
10
_
上記のgrep
は次のように機能します。
-o
_は、括弧内の数字である_\d+
_が検索するものだけを返します。-P
_はgrepのPCRE機能を有効にします(?<=^rate \()
_は、「rate(」で始まる文字列のみを返します「rate」の値をキャッチするには、次のように_command1
_を実行できます。
_$ rate=$(command 1 | grep -oP '(?<=^rate \()\d+'
_
次に、2番目のコマンドでは、その変数を使用します。
_$ command2 -t=${rate}
_
あなたは空想を得て、それをすべて一行にすることができます:
_$ command2 -t=$(command1 | grep -oP '(?<=^rate \()\d+')
_
これは$(..)
実行ブロック内でcommand1を実行し、その結果を取得してcommand2の_-t=..
_スイッチに含めます。