web-dev-qa-db-ja.com

2つのコマンドの出力を比較するにはどうすればよいですか?

2つの類似したディレクトリの内容を比較する最も簡単な方法は次のようになると想像していました

diff `ls old` `ls new`

しかし、なぜこれが機能しないのかわかります。 diffには、私が期待していた2つのストリームではなく、コマンドラインでファイルの大きな長いリストが渡されます。 2つの出力を直接diffに渡すにはどうすればよいですか?

160
Ternary

コマンド置換`…`は、コマンドの出力をコマンドラインに置換するため、diffは両方のディレクトリ内のファイルのリストを引数として参照します。必要なのは、diffがコマンドラインに2つのファイル名を表示し、これらのファイルの内容をディレクトリリストにすることです。それが プロセス置換 が行うことです。

diff <(ls old) <(ls new)

diffの引数は/dev/fd/3および/dev/fd/4のようになります。これらは、bashによって作成された2つのパイプに対応するファイル記述子です。 diffがこれらのファイルを開くと、各パイプの読み取り側に接続されます。各パイプの書き込み側は、lsコマンドに接続されています。

236
Gilles

Zshの場合、=(command)を使用すると、自動的に一時ファイルが作成され、=(command)がファイル自体のパスに置き換えられます。コマンド置換では、$(command)はコマンドのoutputに置き換えられます。

したがって、3つのオプションがあります。

  1. コマンド置換:$(...)
  2. プロセス置換:<(...)
  3. zshフレーバープロセスの置換:=(...)

zshフレーバープロセスの置換、#3は非常に便利であり、比較ツールなどを使用して2つのコマンドの出力を比較するために使用できます。

bcomp  =(ulimit -Sa | sort) =(ulimit -Ha | sort)

Beyond Compareの場合、bcompが比較を開始し、完了するまでwaitsになるので、bcompareの代わりにbcompを使用する必要があることに注意してください。 bcompareを使用すると、比較が開始され、すぐに終了します。これにより、コマンドの出力を保存するために作成された一時ファイルが消えます。

詳細はこちら: http://zsh.sourceforge.net/Intro/intro_7.html

これにも注意してください:

シェルは一時ファイルを作成し、コマンドが終了すると削除することに注意してください。

以下は、zshでサポートされている2つのタイプのプロセス置換の違いです(つまり#2と#3):

Zshのmanページを読むと、<(...)は=(...)に似たプロセス置換の別の形式であることに気付くかもしれません。 2つの間に重要な違いがあります。 <(...)の場合、シェルはファイルではなく名前付きパイプ(FIFO)を作成します。これは、ファイルシステムをいっぱいにしないため、より優れています。しかし、すべての場合に機能するわけではありません。実際、上記の例で=(...)を<(...)に置き換えた場合、fgrep -f <(...)を除いて、すべてが機能しなくなります。パイプを編集したり、メールフォルダーとして開くことはできません。ただし、fgrepは、パイプから単語のリストを読み取ることに問題はありません。 diff <(foo)barが機能しないのはなぜかと思うかもしれません。 diff-バーは機能します。これは、diffが引数の1つが-であることに気付いた場合に一時ファイルを作成し、その標準入力を一時ファイルにコピーするためです。

参照: https://unix.stackexchange.com/questions/393349/difference-between-subshel​​ls-and-process-substitution

3
Ashutosh Jindal

フィッシュシェル

Fish Shellでは、 psub にパイプする必要があります。 Beyond Compare とのherokuとdokkuの設定比較の例を次に示します。

bcompare (ssh [email protected] dokku config myapp | sort | psub) (heroku config -a myapp | sort | psub)
2
WooYek