パイプを使用すると違いがありますか?

パイプを使用すると違いがありますか?

Ubuntu 12.04を使用してください。

パイプ使用(5回):

$ time echo XYZ | sed 's/X/A/g' | sed 's/Y/B/g' | sed 's/Z/C/g'
ABC

real    0m0.005s
user    0m0.000s
sys 0m0.000s
$ time echo XYZ | sed 's/X/A/g' | sed 's/Y/B/g' | sed 's/Z/C/g'
ABC

real    0m0.004s
user    0m0.000s
sys 0m0.000s
$ time echo XYZ | sed 's/X/A/g' | sed 's/Y/B/g' | sed 's/Z/C/g'
ABC

real    0m0.004s
user    0m0.004s
sys 0m0.000s
$ time echo XYZ | sed 's/X/A/g' | sed 's/Y/B/g' | sed 's/Z/C/g'
ABC

real    0m0.005s
user    0m0.000s
sys 0m0.000s
$ time echo XYZ | sed 's/X/A/g' | sed 's/Y/B/g' | sed 's/Z/C/g'
ABC

real    0m0.005s
user    0m0.004s
sys 0m0.000s

パイプがない場合(5回):

$ time echo XYZ | sed 's/X/A/g; s/Y/B/g; s/Z/C/g'
ABC

real    0m0.003s
user    0m0.000s
sys 0m0.004s
$ time echo XYZ | sed 's/X/A/g; s/Y/B/g; s/Z/C/g'
ABC

real    0m0.003s
user    0m0.000s
sys 0m0.000s
$ time echo XYZ | sed 's/X/A/g; s/Y/B/g; s/Z/C/g'
ABC

real    0m0.003s
user    0m0.000s
sys 0m0.000s
$ time echo XYZ | sed 's/X/A/g; s/Y/B/g; s/Z/C/g'
ABC

real    0m0.003s
user    0m0.004s
sys 0m0.000s
$ time echo XYZ | sed 's/X/A/g; s/Y/B/g; s/Z/C/g'
ABC

real    0m0.003s
user    0m0.000s
sys 0m0.000s
$ 

パイプを使用しない方が速いことは明らかです。したがって、スクリプトを最適化するために使用できます。

$ echo ABC | sed 's/A/X/g; s/X/Y/g'
YBC
$ 

私の質問:sedをマージすると、常に同じ出力が生成されますか?

答え1

短い答えは次のとおりです。管路別の置換を実行するには、シェルを数回分岐する必要があります。

一方、sedさまざまな代替コマンドを含む式では、シェルは一度だけフォークできます。

したがって、次のように単一の式にさまざまなコマンドを含める方が効率的です。

sed 's/X/A/g; s/Y/B/g; s/Z/C/g'

2番目の部分に答えるために、上記は次のとおりです。ゆっくり変形:

sed 's/X/A/g' | sed 's/Y/B/g' | sed 's/Z/C/g'

答え2

はい、投稿した2つのコマンドは100%同じで、パイプを使用しないようにスクリプトを安全に変更できます。

echo XYZしかし、あなたの推論には欠陥があります。実際の呼び出しではなく、かかる時間だけを測定していますsed。しかし、パイプを使用しない方がまだ速いことがわかります:)

dennis@spirit:~$ time sh -c 'echo XYZ | sed -e s/X/A/ | sed -e s/Y/B/ | sed -e s/Z/C/'
ABC

real    0m0.009s
user    0m0.000s
sys 0m0.012s
dennis@spirit:~$ time sh -c 'echo XYZ | sed -e s/X/A/ -e s/Y/B/ -e s/Z/C/'
ABC

real    0m0.006s
user    0m0.000s
sys 0m0.006s

答え3

sed条件付きでフォークできるGNU拡張もあります:

sed '/num/s//echo "$((num+1))"/e'

info sed

e

このコマンドを使用すると、シェルコマンドの入力をパターンスペースにパイプできます。置換が行われると、パターン空間内のコマンドが実行され、その出力がパターン空間を置き換えます。末尾の改行は抑制されます。実行するコマンドに NUL 文字が含まれている場合、結果は定義されません。

これはGNU 'sed'拡張です。

関連情報