각 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에 항상 설정 하도록 grep을 설정했습니다 .
export GREP_OPTIONS='--color=always'
내가 달성하려는 것은이 기능을 별칭으로 감싸서 매번 호출 grep
하고 다른 GREP_COLORS
값을 가질 수 있도록하는 것 입니다. 나는 각각의 새로운 파이프 그렙에 대해 여러 개의 셸을 고려해야한다는 것을 이해하고 있으며 이미 사용 된 것을 나타내는 일부 파일 (각 색상마다 하나씩)을 만들어서 이것을 극복하려고 노력하고 있습니다.
나는 약간의 시도를했지만 이상하게도 이것은 “최고”로 작동하는 것으로 보인다. 나는 이것을 내 안에있다 .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 like”도구를 찾고 있지 않습니다. 이미 멋진 펄 제안을 게시 한 @terdon 에게 죄송합니다 .
답변
다른 접근법이 있습니다. 다른 답변으로 이미 게시 한 작은 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;
답변
grep
파이프에서 각 호출은 별도의 쉘에서 실행되므로 파이프 사이에 상태를 전달해야합니다. 다음 솔루션은 색상 색인을 유지하는 파일과 동시 호출이 동일한 값을 읽지 않도록하는 잠금 파일을 사용하여 처리하는 적절한 방법입니다.
#!/usr/bin/env bash
color_index_file=~/.gitcolor
color_index_lock_file=/tmp/$(basename $0)
colors=()
for index in {31..34}
do
colors+=("01;$index")
done
until mkdir "$color_index_lock_file" 2>/dev/null
do
:
done
color_index=$(($(cat "$color_index_file" || echo 0) + 1))
if [[ $color_index -ge ${#colors[@]} ]]
then
color_index=0
fi
printf "$color_index" > "$color_index_file"
rmdir "$color_index_lock_file"
GREP_COLORS="mt=01;${colors[$color_index]}" grep --color=always "$@"
사본의 이름을 지정한 것으로 가정하여 테스트 cgrep
하십시오 PATH
.
echo foobarbaz | cgrep foo | cgrep bar | cgrep baz
답변
정규 표현식에 익숙하다면 grc 및 grcat을 확인하십시오. grc는 grcat을 호출합니다.
grcat은 구성 파일을 사용하여 각 색상으로 표시 할 텍스트와 일치시키는 정규식을 추가 할 수 있습니다. 또한 다른 많은 옵션이 있습니다. 기본적으로 시스템 로그 파일을 채색합니다.
최종 스크립트에 대해 생각한 내용에 따라 하나의 명령으로 출력을 채색 할 수 있습니다.
트릭은 데이터 소스의 각 “필드”에 대해 정규 표현식을 올바르게 지정하는 것입니다. 데이터의 구조가 비교적 균일하면 훨씬 쉽습니다.
마지막으로 시도했을 때 너무 멀리 가지 않았지만 이전보다 정규 표현식에 조금 더 좋기 때문에 다시 시도해야 할 수도 있습니다.
터미널 장치에 직접 정보 (색상 변경 등)를 보내는 데 사용할 수있는 tput 명령도 있습니다.
두 가지 방법 모두 아래 게시물에 포함되어 있습니다. find 명령에 대해 설명하지만 모든 명령의 출력에 적용 할 수 있습니다.