2017-05-16 2 views
0

Ich habe den folgenden Code:Sed Einfärben der Ausgang funktioniert nicht wie erwartet

#!/bin/bash 

reset=$(tput sgr0) 
bold=$(tput bold) 

red=$(tput setaf 1) 
white=$(tput setaf 7) 

pattern[0]='[0-9]' 
replacement[0]="${white}${bold}&${reset}" 

pattern[1]='[a-z]' 
replacement[1]="${red}${bold}&${reset}" 

args=() 
for ((i=0; i < ${#pattern[@]}; i++)) ; do 
    args+=(-e "s/${pattern[i]}/${replacement[i]}/g") 
done 

echo "asdf1234" | sed "${args[@]}" 

Es gibt:

asdfmm1mmm2mmm3mmm4m 

dh zusätzliche m Zeichen hinzugefügt und alle Buchstaben sind rot, die Ziffern sind nicht hervorgehoben.

Mein Wunsch ist es, Buchstaben in rot und Ziffern in weiß zu haben. Wie kann ich das machen?

Antwort

1

wie diese versuchen:

#!/bin/bash 

reset=$(tput sgr0)  # \001 
bold=$(tput bold)  # \002 

red=$(tput setaf 1) # \003 
white=$(tput setaf 7) # \004 

pattern[0]='[0-9]' 
replacement[0]=$'\004\002&\001' 

pattern[1]='[a-z]' 
replacement[1]=$'\003\002&\001' 

args=() 
for ((i=0; i < ${#pattern[@]}; i++)) ; do 
    args+=(-e "s/${pattern[i]}/${replacement[i]}/g") 
done 

echo "asdf1234" | sed "${args[@]}" \ 
    | sed -e $'s/\001/'$reset'/g' \ 
      -e $'s/\002/'$bold'/g' \ 
      -e $'s/\003/'$red'/g' \ 
      -e $'s/\004/'$white'/g' 

Ausgang auf meinem System:

screenshot

+0

Es könnte brechen, wenn die Eingabe \ 001 usw. enthält. – choroba

+0

Danke. Das funktioniert. Die '00x'-Codes machen den Code jedoch unlesbar. Ich bin bereit, die Variablennamen zu verwenden, um sie lesbar zu halten. Können Sie bitte beraten, wie das geht? – george

+0

dann nur noch "\ ooo" zu vars zuordnen. z.B .: '_red = $ '\ 003'' – pynexj

1

Der Grund, warum es nicht funktioniert, ist, dass der Code für weiß und fett Zeichen enthält, die durch das zweite Muster übereinstimmen. sed wendet alle Muster sequentiell auf jede Eingabezeile an, z.

echo a | sed -e s/a/b/ -e s/b/c/ # Outputs "c". 

Was Sie brauchen, ist einen einzigen Ausdruck mit verschiedenem Ersatz zu verwenden, abhängig von den erfassten Daten, die possiblee.g ist. in Perl:

#! /usr/bin/perl 
use warnings; 
use strict; 
use feature qw{ say }; 

use List::Util qw{ first }; 
use Term::ANSIColor qw{ color }; 


my $reset = color('reset'); 
my $bold = color('bold'); 
my $red = color('red'); 
my $white = color('white'); 

my (@pattern, @replacement); 

push @pattern, '[0-9]'; 
push @replacement, "$white$bold"; 

push @pattern, '[a-z]'; 
push @replacement, "$red$bold"; 

my $regex = join '|', map "($_)", @pattern; 

my $string = 'asdf1234'; 

$string =~ s/$regex/ 
    my $i = first { defined $+[$_] } 1 .. $#+; 
    $replacement[$i-1] . "$+$reset" 
    /ge; 

say $string; 

Gerade den letzten Teil in

ändern
while (my $string = <>) { 
    $string =~ s/$regex/ 
     my $i = first { defined $+[$_] } 1 .. $#+; 
     $replacement[$i-1] . "$+$reset" 
     /ge; 

    print $string; 
} 

, um es als Argument gegeben Prozess stdin oder Dateien zu machen.

+0

So, wie es funktioniert? – george

+0

Perl zur Rettung! – choroba

+0

Die Frage ist für bash. – george

Verwandte Themen