That's the behavior of POSIX and UNIX conformant echo
. With a UNIX conformant echo
, you'd write:
echo 'Check Script\c'
Best is not to use echo but printf instead which has fewer portability issues.
printf %s 'Check Script'
Note that POSIX allows -n
as an extension (but with unspecified behavior). echo -e
is meant to output -e\n
, so in that regard, bash
and zsh
are not POSIX conformant.
Noting a comment about "Easy using awk", that would be relative to sed.
OP was describing a not-very-well documented feature of logcat
(see commit) which tells logcat
to assign hardcoded-colors to each line based on the log entry's priority.
There are other choices, such as logcat-color, PID cat and coloredlogcat which let you color different fields, e.g., raising the possibility of multiple colors per line.
Here's an awk script which recognizes the hardcoded logcat colors, but allows multiple colors per line:
#!/usr/bin/awk -f
BEGIN {
colors["0"] = "Black";
colors["38;5;40"] = "Green";
colors["38;5;196"] = "Red";
colors["38;5;75"] = "Blue";
colors["38;5;166"] = "Sienna";
colors["38;5;231"] = "DarkSlateGray";
color = "";
last = "";
this = "";
save = "";
}
/\033/ {
done = "";
while ( $0 ~ /\033\[[;0-9]*m/ ) {
mark = match($0, /\033\[[;0-9]*m/ );
if ( mark > 1 ) { done = done substr($0, 1, mark - 1); }
item = substr($0, RSTART + 2, RLENGTH - 3);
$0 = substr($0, RSTART + RLENGTH);
if ( match($0, /^\033\[[;0-9]*m/ ) > 0 ) continue;
color = colors[item];
if ( done == "" ) this = color;
if ( item == "0" ) color = "";
if ( color == "" ) {
if ( $0 != "" ) last = color;
$0 = "[/COLOR]" $0;
} else if (color != last) {
$0 = "[COLOR=\"" color "\"]" $0;
last = color;
}
}
$0 = done $0;
if ( last != "" ) $0 = $0 "[/COLOR]";
}
{
if ( NR > 1 ) {
if ( this == last) sub("\[/COLOR\]$", "", save);
print save;
}
save = $0;
}
END {
if ( NR > 0 ) print save;
}
With the original example:
^[[0m^[[38;5;231mV/Zygote ( 4666): Switching descriptor 55 to /dev/null
^[[0m^[[38;5;231mV/Zygote ( 4666): Switching descriptor 9 to /dev/null
^[[0m^[[38;5;40mI/ggheart ( 1111): onStop
^[[0m^[[38;5;40mI/Test ( 1111): onStop
^[[0m^[[38;5;75mD/ActivityThread( 4666): handleBindApplication:com.mxtech.videoplayer.ad
^[[0m^[[38;5;75mD/ActivityThread( 4666): setTargetHeapUtilization:0.75
^[[0m^[[38;5;75mD/ActivityThread( 4666): setTargetHeapMinFree:2097152
you would get the requested output:
[COLOR="DarkSlateGray"]V/Zygote ( 4666): Switching descriptor 55 to /dev/null
V/Zygote ( 4666): Switching descriptor 9 to /dev/null
[COLOR="Green"]I/ggheart ( 1111): onStop
I/Test ( 1111): onStop
[COLOR="Blue"]D/ActivityThread( 4666): handleBindApplication:com.mxtech.videoplayer.ad
D/ActivityThread( 4666): setTargetHeapUtilization:0.75
D/ActivityThread( 4666): setTargetHeapMinFree:2097152[/COLOR]
but changing the input to
^[[0m^[[38;5;231mV/Zygote ( 4666): Switching descriptor 55 to /dev/null
^[[0m^[[38;5;231mV/Zygote ( 4666): Switching descriptor 9 to /dev/null
^[[0m^[[38;5;40mI/ggheart ( ^[[38;5;75mI/ggheart 1111^[[0m): onStop
^[[0m^[[38;5;40mI/Test ( 1111): onStop
^[[0m^[[38;5;75mD/ActivityThread( 4666): handleBindApplication:com.mxtech.videoplayer.ad
^[[0m^[[38;5;75mD/ActivityThread( 4666): setTargetHeapUtilization:0.75
^[[0m^[[38;5;75mD/ActivityThread( 4666): setTargetHeapMinFree:2097152
gives this result:
[COLOR="DarkSlateGray"]V/Zygote ( 4666): Switching descriptor 55 to /dev/null
V/Zygote ( 4666): Switching descriptor 9 to /dev/null[/COLOR]
[COLOR="Green"]I/ggheart ( [COLOR="Blue"]I/ggheart 1111[/COLOR]): onStop
[COLOR="Green"]I/Test ( 1111): onStop
[COLOR="Blue"]D/ActivityThread( 4666): handleBindApplication:com.mxtech.videoplayer.ad
D/ActivityThread( 4666): setTargetHeapUtilization:0.75
D/ActivityThread( 4666): setTargetHeapMinFree:2097152[/COLOR]
Best Answer
You probably are using different shells with different
echo
implementations. At least inbash
's implementation of echo, interpretation of escape sequences is not enabled by default (you have to enable it with the-e
switch).In any case,
printf
is generally more conformant between environments. Try using the following instead: