各grepコマンドに結果を異なる色で強調表示させたいとします。次の行を使用して手動で実行できます。
ls -l GREP_COLORS='mt=01;32' grep c | GREP_COLORS='mt=01;31' grep o | GREP_COLORS='mt=01;34' grep n | GREP_COLORS='mt=01;36' grep f
各c
文字は緑色で強調表示され、各o
文字は赤色で強調表示されます。
--color=always
この例が正しく機能するには、常にgrepコマンドを使用する必要があります。.bashrc
grepには常に色があるようにこれを私の設定に設定しました。
export GREP_OPTIONS='--color=always'
私が達成したいのは、この関数を別名でラップして呼び出しgrep
、毎回異なる値を取得できるようにすることです。GREP_COLORS
私はそれぞれの新しいパイプライン grep が複数のシェルを考慮しなければならないことを理解しており、使用されたことを示すためにいくつかのファイル (各色ごとに 1 つ) を生成してこの問題を解決しようとしました。
私はいくつか試してみましたが、奇妙なことに、これは「最高」で動作するようです。私のもの.bashrc
:
alias mg="mygrep"
mygrep(){
# define possible colors
COLORS=("01;32" "01;31" "01;34" "01;36")
COUNTER=0
NUM=0
# as long as the color has already been used, keep searching
while [ -f /home/lior/Desktop/mygrep_$NUM ]; do
# get a random index
let NUM=`shuf --input-range=0-$(( ${#COLORS[*]} - 1 )) | head -1`
wait ${!}
$(( COUNTER+=1 ))
if [ "$COUNTER" -ge ${#COLORS[@]} ]; then
# remove all color locks
rm /home/lior/Desktop/mygrep_*
wait ${!}
fi
done
# mark this color as used
touch /home/lior/Desktop/mygrep_$NUM
wait ${!}
# lets go!
GREP_COLORS="mt=${COLORS[$NUM]}" grep "$@"
}
私はこのエイリアスを次のように使用します。
ll | mg c | mg o | mg n | mg f
結果はとても素敵です。しかし、いくつかのエラーは毎回少しずつ異なります。以下はいくつかのスクリーンショットです。
シェルがパイプで接続された各コマンドを実行すると、以前の関数はまだ実行を完了していないようです。存在しなくなったファイルを削除しようとします。command not found
他のエラーがどこで発生するのかわかりません。
ご覧のとおり、ファイルwait
操作を完了するためにいくつかのコマンドを入力しましたが、うまく動作しないようです。私が試した別の方法は共有メモリを使用することでしたが、/dev/shm
同様の結果が出ました。
私が望む結果を得るにはどうすればよいですか?
メモ:
grepコマンドに使用したい機能が多く、パイプ間に異なるロジックを挿入したいので、すべてのクエリを一度に提供したくないので、単にgrepコマンドをラップする答えを探しています。 。私は他の「grepのような」ツールも探していません。残念@テデン素晴らしいPerl提案を投稿した人は誰ですか?
ベストアンサー1
これは別のアプローチです。 Perlスクリプトがありますすでに公開済み別の答えでは、ユーザーが提供したパターンは異なる色で強調表示されます。このスクリプトを少し変更したバージョンは次のとおりですgrep
。
#!/usr/bin/env perl
use Getopt::Std;
use strict;
use Term::ANSIColor;
my %opts;
getopts('hic:l:',\%opts);
if ($opts{h}){
print<<EoF;
Use -l to specify the pattern(s) to highlight. To specify more than one
pattern use commas.
-l : A Perl regular expression to be colored. Multiple expressions can be
passed as comma separated values: -l foo,bar,baz
-i : makes the search case sensitive
-c : comma separated list of colors;
EoF
exit(0);
}
my $case_sensitive=$opts{i}||undef;
my @color=('bold red','bold blue', 'bold yellow', 'bold green',
'bold magenta', 'bold cyan', 'yellow on_blue',
'bright_white on_yellow', 'bright_yellow on_red', 'white on_black');
if ($opts{c}) {
@color=split(/,/,$opts{c});
}
my @patterns;
if($opts{l}){
@patterns=split(/,/,$opts{l});
}
else{
$patterns[0]='\*';
}
# Setting $| to non-zero forces a flush right away and after
# every write or print on the currently selected output channel.
$|=1;
while (my $line=<>)
{
my $want=0;
for (my $c=0; $c<=$#patterns; $c++){
if($case_sensitive){
if($line=~/$patterns[$c]/){
$line=~s/($patterns[$c])/color("$color[$c]").$1.color("reset")/ge;
$want++;
}
}
else{
if($line=~/$patterns[$c]/i){
$line=~s/($patterns[$c])/color("$color[$c]").$1.color("reset")/ige;
$want++;
}
}
}
print STDOUT $line if $want>0;
}
cgrep
このスクリプトをどこかに保存してPATH
実行可能にすると、最大10のモードを指定でき、各モードは異なる色で印刷されます。
$ cgrep -h
Use -l to specify the pattern(s) to highlight. To specify more than one
pattern use commas.
-l : A Perl regular expression to be colored. Multiple expressions can be
passed as comma separated values: -l foo,bar,baz
-i : makes the search case sensitive
-c : comma separated list of colors;