どのようにできるのか
{$several_commands} | less
less
をいくつかのファイルと見なし、:n
および:p
を使用してナビゲーションを有効にします。
それはより明確な説明ではないかもしれないので、例を考えてみましょう。現在機能を持っています
svndiff ()
{
for a in `svn status | \grep ^M | sed 's/M //'`;
do
svn diff $a | less;
done
}
目的は明らかに、less
を使用して、変更したすべてのファイルの違いを確認することです。しかし、この構文では、1つの「ファイル」を閉じて次のファイルを開くために、キーQ
を使用する必要があります。 less
コマンド:n
(次のファイル)と:p
(前のファイル)を使用してファイル間を移動できるようにしたいと思います。どうやってやるの ?
プロセス置換を使用できます:
less -f <(svn diff this) <(svn diff that)
しかし、それをループで使用するのは困難です。おそらく一時ファイルを使用するのが最善です:
#!/bin/bash
dir=$(mktemp -d)
outfiles=()
IFS=$'\n'
set -f
for file in $(svn status | \grep ^M | sed 's/M //') ; do
outfile=${file#.} # remove leading dot (if any)
outfile=${outfile//\//__} # replace slashes (if any) with __
svn diff "$file" > "$dir/$outfile";
outfiles+=("$dir/$outfile") # collect the filenames to an array
done
less "${outfiles[@]}"
rm -r "$dir"
上記は、一時ファイルの名前にファイル名を表示したままにし、スラッシュと先頭のドットのクリーンアップを試みます。 (./foo/bar
のようなパスを取得する場合。svn
がファイル名を出力する方法を思い出せませんが、とにかく...)
配列は順序を維持するためにありますが、@ Kusalanandaが言ったように、順序が重要でない場合は、代わりに"$dir"/*
を実行できます。 set -f
およびIFS=$'\n'
誰かがグロブ文字または空白を含むファイル名を作成した場合。
もちろん、スクリプトを少し簡略化して、代わりに番号付き一時ファイルを作成することもできます。
:n
と:p
を使用して移動する場合は、コマンドを実行して出力をファイルに出力し、次にless
それらを使用する以外に方法はありません。
svndiff ()
{
d=$(mktemp -d /tmp/svndiffsXXXXX)
for a in $(svn status | \grep ^M | sed 's/M //');
do
svn diff "$a" > $(mktemp $d/diffXXXXX) 2>&1;
done
less "$d"/diff*
rm -fr "$d"
}
(必要に応じて番号をお知らせください。番号を付けることができます。)
それ以外の場合は、すべてのコマンドを実行するシェルを呼び出し、連結された出力をless
にパイプします。
GNU Parallelを使用すると、次のようなことができます:
files=$(svn status | \grep ^M | sed 's/M //' |
parallel --files svn diff {})
less $files
rm $files