grep
のカラー出力が必要です。
.... だが
find ... | xargs grep
では機能しません。これを解決するには?
...しかし、私は賞金を与えることができません
私を失礼、傲慢、侮辱的、虐待的と呼びます....
回避策しか表示されません-解決策はありません。質問に答える回答はありませんでした。
ご清聴ありがとうございました。
OPがオプションが不適切であると述べた理由のいくつかは、実際には根拠がありません。ここでは、OPの戦略4を使用してどのような効果があるかを示します。
ほとんどのディストリビューションでは、grep
は/bin
(標準)または/usr/bin
(OpenSUSEなど)にインストールされ、デフォルトのPATH
は/usr/local/bin
または/bin
の前に/usr/bin
を含みます。つまり、/usr/local/bin/grep
を
#!/bin/sh
exec /bin/grep --color=auto "$@"
ここで、/bin/sh
は、ディストリビューションによって提供されるPOSIX互換シェルであり、通常はbashまたはdashです。 grep
が/usr/bin
にある場合は、
#!/bin/sh
exec /usr/bin/grep --color=auto "$@"
このスクリプトのオーバーヘッドは最小限です。 exec
ステートメントは、スクリプトインタープリターがgrep
バイナリーに置き換えられることを意味します。つまり、grep
が実行されている間、シェルはメモリに残りません。したがって、唯一のオーバーヘッドは、スクリプトインタープリターの1つの余分な実行、つまり実時間での小さな待ち時間です。レイテンシはほぼ一定で(grep
とsh
が既にページキャッシュにあるかどうか、および使用可能なI/O帯域幅の量によってのみ異なります)、grep
の実行時間や処理するデータの量には依存しません。
それで、その待ち時間、つまりラッパースクリプトによって追加されるオーバーヘッドはどのくらいですか?
確認するには、上記のスクリプトを作成して実行します。
time /bin/grep --version
time /usr/local/bin/grep --version
私のマシンでは、前者は(多数の実行にわたって)0.005秒のリアルタイムで実行されますが、後者は0.006秒のリアルタイムで実行されます。したがって、私のマシンでラッパーを使用するオーバーヘッドは、呼び出しごとに0.001秒(またはそれ以下)です。
これは重要ではありません。
また、多くの一般的なアプリケーションとユーティリティが同じアプローチを使用しているため、これについて「汚い」ことは何も見落としています。お使いのマシンの/bin
と/usr/bin
でそのようなリストを表示するには、次のコマンドを実行します。
file /bin/* /usr/bin/* | sed -ne 's/:.*Shell script.*$//p'
私のマシンでは、上記の出力には、egrep
、fgrep
、zgrep
、which
、7z
、chromium-browser
、ldd
、およびxfig
が含まれます。ラッパースクリプトに依存するためにディストリビューション全体を「ダーティ」と見なさない限り、そのようなラッパースクリプトを「ダーティ」と見なす理由はありません。
問題に関しては、そのようなラッパースクリプトは以下を引き起こす可能性があります。
(スクリプトではなく)人間のユーザーのみが、出力が端末への出力の場合にデフォルトでカラーサポートになっているバージョンのgrepを使用している場合、ラッパースクリプトの名前は、colorgrep
またはcgrep
、またはOPが適合するものとすることができます。
これにより、grep
の動作がまったく変更されないため、考えられるすべての互換性の問題が回避されます。
ラッパースクリプトでgrep
オプションを有効にするが、新しい問題を回避する方法で:
GREP_OPTS
がサポートされていない場合でも(すでに非推奨であるため)、ラッパースクリプトを簡単に書き換えて、カスタムGREP_OPTIONS
をサポートできます。このように、ユーザーはexport "GREP_OPTIONS=--color=auto"
または類似のものを自分のプロファイルに追加するだけです。 /usr/local/bin/grep
は次に
#!/bin/sh
exec /bin/grep $GREP_OPTIONS "$@"
$GREP_OPTIONS
は引用符で囲まれていないため、ユーザーは複数のオプションを指定できます。
私のシステムでは、time /usr/local/bin/grep --version
を空にして、またはGREP_OPTIONS
を指定してGREP_OPTIONS=--color=auto
を実行すると、以前のバージョンのラッパースクリプトと同じくらい高速です。つまり、通常のgrep
よりも実行に通常1ミリ秒長くかかります。
この最後のバージョンは、私が個人的に使用することをお勧めするバージョンです。
要約すると、OPの戦略4:
grep
開発者が推奨するエリア
実装するのは簡単です(2行)
わずかなオーバーヘッドがあります(この特定のラップトップでの呼び出しごとに1ミリ秒の追加レイテンシ。各マシンで簡単に確認できます)
GREP_OPTS
サポートを追加するラッパースクリプトとして実装できます(非推奨/サポートされていないGREP_OPTIONS
を置き換えるため)
スクリプトまたは既存のユーザーにまったく影響を与えない(colorgrep
/cgrep
として)実装可能
これはすでにLinuxディストリビューションで広く使用されている手法であるため、「ダーティー」ではなく一般的な手法です。
別個のラッパー(colorgrep
/cgrep
)として実装した場合、grep
の動作にまったく影響しないため、新しい問題を作成できません。 GREP_OPTS
のサポートを追加するラッパースクリプトとして実装する場合、GREP_OPTS=--color=auto
を使用すると、デフォルトの--color=auto
を上流に追加する場合とまったく同じリスク(既存のスクリプトに関する問題)が発生します。したがって、これが「解決するよりも多くの問題を作成する」というコメントは完全に正しくありません。追加の問題は作成されません。
GREP_OPTIONS
変数は廃止予定です。grep
がスクリプトのどこかで呼び出され、スクリプトが変数からの代替オプションで機能しない場合、問題が発生する傾向があります。 grep
のラッパースクリプトを作成すると、同じ問題が発生します別の名前を付けない限り。
$ cat ~/bin/cgrep
#!/bin/sh
exec grep --color=always "$@"
$ find … -exec cgrep … {} +
または、お気に入りのオプションを変数に保存します。 zsh以外のシェルでは、オプションにワイルドカード文字(\[*?
)ですが、それ以外の場合は、引用符で囲まれていない変数を使用して、引数付きのコマンドを取得できます。
cgrep=(grep --color=always)
find … -exec $cgrep … {} +
GNUおよびBSD grepはディレクトリツリーを再帰的に処理できるため、ほとんどの場合find
をgrep
と組み合わせて使用する必要がなくなります。
あなたが最初の戦略で提供するドキュメントは言う:
代わりにエイリアスまたはスクリプトを使用してください。たとえば、grepがディレクトリ ‘/ usr/bin’にある場合、$ HOME/binをPATHの先頭に追加して、以下を含む実行可能スクリプト$ HOME/bin/grepを作成できます。
#! /bin/sh
export PATH=/usr/bin
exec grep --color=auto --devices=skip "$@"
したがって、エイリアスが不可能な場合は、ラッパースクリプトが唯一の方法です。
最も簡単な方法は、エイリアスを使用することです(戦略3)。 xargs
コマンドを本当に気にしている場合でも、bash関数でオーバーライドできます。
alias grep='grep --color'
xargs() {
local args
for ((i=1; i<=$#; i++))
do
if [[ "-E -L -P -I -s -d" == *"${!i}"* ]]; then
((i=i+1))
Elif [[ ${!i:0:1} != "-" ]]; then
if [[ ${!i} == "grep" ]]; then
args="--color"
fi
/usr/bin/xargs ${@:1:i} $args ${@:i+1}
return;
fi
done
}
しかし、これはgrep
チームが推奨するソリューションであると思われるラッパーコマンドを使用するよりも優れています。
/usr/local/bin/grep:
#!/bin/bash
/bin/grep --color "$@"
私の考えでは、grep
開発者チームに連絡して、grep
の色を有効にするGREP_OPTIONS
変数の簡単な置き換えを提供するよう依頼する必要があります。いくつかの環境変数に。
彼らがデフォルトでcolor
オプションを有効にするのは、またはGREP_COLORS
が設定されている場合は非常に簡単です。
これは、@ NominalAnimalによる上位の回答からの解決策ですが、警告には通常のgrep: ...
が(/bin/grep: ...
ではなく)含まれています。
#!/bin/bash
exec -a grep /bin/grep --color=auto "$@"