2つのパイプコマンドを1つのコマンドに結合する

2つのパイプコマンドを1つのコマンドに結合する

私は次の 2 つのコードを持っており、それらを 1 つに結合/結合したいと考えています。

rostopic echo /cmd_vel | grep -A 3 angular | grep -v x | grep -v y | cut -d : -f 2

rostopic echo /cmd_vel | grep -A 1 linear | grep -v linear | cut -d : -f 2

どうやってするか?

答え1

rostopic echo /cmd_vel | awk -F: '
         /angular/ { m = "z" ; next};   # we want z from angular
         /linear/  { m = "x" ; next};   # and x from linear
         { 
           gsub(/ /,"",$1);    # strip spaces from $1

           if ($1 == m) {      
             gsub(/ /,"",$2);  # strip spaces from $2
             print $2;         
             m = ""            # reset m so it doesnt match anything
           } 
         }'

これは、の出力rostopic echo /cmd_velがで説明したものと同じであることを前提としています。ロストピックエコーの使用例:

linear:
  x: 2.0
  y: 0.0
  z: 0.0
angular: 
  x: 0.0
  y: 0.0
  z: 0.0
---

その入力による awk スクリプトの出力は次のようになります。

2.0
0.0

つまり、「線形」の後の最初の行の2番目のフィールドと、しない「angular」の後に x または y (つまり z である必要があります) を含めます。


同じスクリプトの少しシンプルなバージョンを次に示します。フィールド区切り文字を「1 つ以上の空白文字で、オプションでコロン文字が前に付くもの」( を使用-F':?[[:space:]]+') に設定し、この変更がフィールドの番号付けに影響することを考慮すると、 を使用する必要はありませんgsub()

rostopic echo /cmd_vel | 
  awk -F':?[[:space:]]+' '
      /angular/ { m = "z" ; next};
      /linear/  { m = "x" ; next};
      $2 && $2 == m { print $3 ; m = ""}'

答え2

tee出力プロセスの置換を使用すると、次のようになります。

rostopic echo /cmd_vel \
| tee >(grep -A 3 angular | grep -v x | grep -v y | cut -d : -f 2) \
| grep -A 1 linear | grep -v linear | cut -d : -f 2

答え3

に似ているもう一つの素晴らしい答え、次のようにすれば、ある程度「並列」で実行できますpaste

paste <(rostopic echo /cmd_vel | grep -A 3 angular | grep -v x | grep -v y | cut -d : -f 2) <(rostopic echo /cmd_vel | grep -A 1 linear | grep -v linear | cut -d : -f 2)

パイプ入力は受け付けないteeが、もっと早く。

関連情報