![색상 표현](https://linux55.com/image/4614/%EC%83%89%EC%83%81%20%ED%91%9C%ED%98%84.png)
각 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이 여러 셸을 고려해야 한다는 것을 이해하고 있으며, 사용되었음을 보여주기 위해 일부 파일(각 색상당 하나씩)을 생성하여 이 문제를 해결하려고 노력했습니다.
나는 몇 가지를 시도했지만 이상하게도 이것이 "최고"로 작동하는 것 같습니다. 내 거 .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;
답변2
파이프라인의 각 호출은 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
답변3
정규식에 능숙하다면 grc 및 grcat을 확인하는 것이 좋습니다. grc는 grcat을 호출합니다.
grcat은 각 색상으로 표시하려는 텍스트와 일치하도록 정규식을 추가하는 구성 파일을 사용합니다. 또한 다른 많은 옵션도 있습니다. 기본적으로 시스템 로그 파일에 색상이 지정됩니다.
최종 스크립트에 대한 아이디어에 따라 단 하나의 명령으로 출력에 색상을 적용할 수도 있습니다.
비결은 데이터 소스의 각 "필드"에 대해 정규식을 올바르게 지정하는 것입니다. 데이터 구조가 상대적으로 균일하면 훨씬 쉽습니다.
지난번에 시도했을 때는 그리 멀리 가지 못했지만, 그 때보다 정규 표현식에 조금 더 능숙해졌기 때문에 지금 다시 시도해볼 수도 있습니다.
정보(예: 색상 변경)를 최종 장치에 직접 보내는 데 사용할 수 있는 tput 명령도 있습니다.
다음 게시물에서는 두 가지 방법을 모두 설명합니다. find 명령에 대해 설명하지만 모든 명령의 출력에 적용될 수 있습니다.
답변4
나는 이것이 자주 필요하며 bash에서 구현된 스크립트를 포함하여 여러 솔루션을 시도했습니다.형광펜. 그러나 여러 패턴, 중복 일치 또는 다음과 같은 기타 특수한 경우를 사용하는 경우하나의특징성냥.
그래서 나는 나만의 셰이더를 출시하기로 결정했습니다.
색상 표현
- 여기에는 정의된 색상 논리가 있습니다. 마지막 일치 항목에 따라 색상이 결정됩니다.
- 캡처 그룹을 사용하면 그룹 내용만 색상이 지정됩니다.
참고: grep과 달리 일치하는 줄뿐만 아니라 모든 입력 줄을 인쇄합니다. 따라서 필터링이 필요한 경우 grep을 사용한 다음 colorexp를 파이프하십시오.
예
기본 사용법
- 텍스트만 색칠하거나 배경만 색칠하려면
-h
/ 옵션을 사용하세요 .-H
겹치는 경기 - 마지막 경기가 승리합니다.
- 모든 일치 항목에 색상이 지정되며 마지막 일치 항목의 색상이 사용됩니다.
캡처 그룹
- 캡처 그룹을 사용하면 일치하는 그룹 콘텐츠만 색상이 지정됩니다.
패턴의 각 그룹에는 서로 다른 색상이 있습니다.
- 하나의 모드만 지정하면 기본적으로 캡처 그룹마다 다른 색상이 사용됩니다.
- 여러 패턴이 있는 경우 이
-G
옵션을 사용하여 각 그룹의 색상을 강제로 변경할 수 있습니다.
- 여러 패턴이 있는 경우 이
패턴의 모든 그룹에 동일한 색상을 사용하십시오.
- 여러 패턴이 제공되면 기본적으로 패턴의 모든 캡처 그룹에 동일한 색상이 사용됩니다.
- 단일 패턴의 경우 이
-g
옵션을 사용하여 단일 색상을 강제로 적용할 수 있습니다.
- 단일 패턴의 경우 이