Bạn có thể làm điều này bằng cách chuyển qua bộ lọc, đó chỉ là vấn đề thêm mã ANSI thích hợp trước và sau mỗi dòng:
http://en.wikipedia.org/wiki/ANSI_escape_fterences#Colors
Tôi không thể tìm thấy một công cụ thực sự làm điều này sau vài phút googling, điều này hơi kỳ quặc khi xem xét việc viết nó dễ dàng như thế nào.
Đây là một ý tưởng sử dụng C:
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
#include <errno.h>
/* std=gnu99 required */
// ANSI reset sequence
#define RESET "\033[0m\n"
// length of RESET
#define RLEN 5
// size for read buffer
#define BUFSZ 16384
// max length of start sequence
#define START_MAX 12
void usage (const char *name) {
printf("Usage: %s [-1 N -2 N -b -e | -h]\n", name);
puts("-1 is the foreground color, -2 is the background.\n"
"'N' is one of the numbers below, corresponding to a color\n"
"(if your terminal is not using the standard palette, these may be different):\n"
"\t0 black\n"
"\t1 red\n"
"\t2 green\n"
"\t3 yellow\n"
"\t4 blue\n"
"\t5 magenta\n"
"\t6 cyan\n"
"\t7 white\n"
"-b sets the foreground to be brighter/bolder.\n"
"-e will print to standard error instead of standard out.\n"
"-h will print this message.\n"
);
exit (1);
}
// adds character in place and increments pointer
void appendChar (char **end, char c) {
*(*end) = c;
(*end)++;
}
int main (int argc, char *const argv[]) {
// no point in no arguments...
if (argc < 2) usage(argv[0]);
// process options
const char options[]="1:2:beh";
int opt,
set = 0,
output = STDOUT_FILENO;
char line[BUFSZ] = "\033[", // ANSI escape
*p = &line[2];
// loop thru options
while ((opt = getopt(argc, argv, options)) > 0) {
if (p - line > START_MAX) usage(argv[0]);
switch (opt) {
case '?': usage(argv[0]);
case '1': // foreground color
if (
optarg[1] != '\0'
|| optarg[0] < '0'
|| optarg[0] > '7'
) usage(argv[0]);
if (set) appendChar(&p, ';');
appendChar(&p, '3');
appendChar(&p, optarg[0]);
set = 1;
break;
case '2': // background color
if (
optarg[1] != '\0'
|| optarg[0] < '0'
|| optarg[0] > '7'
) usage(argv[0]);
if (set) appendChar(&p, ';');
appendChar(&p, '4');
appendChar(&p, optarg[0]);
set = 1;
break;
case 'b': // set bright/bold
if (set) appendChar(&p, ';');
appendChar(&p, '1');
set = 1;
break;
case 'e': // use stderr
output = STDERR_FILENO;
break;
case 'h': usage(argv[0]);
default: usage(argv[0]);
}
}
// finish 'start' sequence
appendChar(&p, 'm');
// main loop
// set non-block on input descriptor
int flags = fcntl(STDIN_FILENO, F_GETFL, 0);
fcntl(STDIN_FILENO, F_SETFL, flags | O_NONBLOCK);
// len of start sequence
const size_t slen = p - line,
// max length of data to read
rmax = BUFSZ - (slen + RLEN);
// actual amount of data read
ssize_t r;
// index of current position in output line
size_t cur = slen;
// read buffer
char buffer[rmax];
while ((r = read(STDIN_FILENO, buffer, rmax))) {
if (!r) break; // EOF
if (r < 1) {
if (errno == EAGAIN) continue;
break; // done, error
}
// loop thru input chunk byte by byte
// this is all fine for utf-8
for (int i = 0; i < r; i++) {
if (buffer[i] == '\n' || cur == rmax) {
// append reset sequence
for (int j = 0; j < RLEN; j++) line[j+cur] = RESET[j];
// write out start sequence + buffer + reset
write(output, line, cur+RLEN);
cur = slen;
} else line[cur++] = buffer[i];
}
}
// write out any buffered data
if (cur > slen) {
for (int j = 0; j < RLEN; j++) line[j+cur] = RESET[j];
write(output, line, cur+RLEN);
}
// flush
fsync(output);
// the end
return r;
}
Tôi nghĩ rằng đó là về hiệu quả như bạn sẽ nhận được. Các write()
nhu cầu để làm toàn bộ phù hợp với trình tự ANSI tất cả chỉ trong một bước - thử nghiệm này với dĩa song song dẫn đến đan xen nếu chuỗi ANSI và nội dung bộ đệm được thực hiện riêng rẽ.
Điều đó cần được biên dịch -std=gnu99
vì getopt
không phải là một phần của tiêu chuẩn C99 nhưng nó là một phần của GNU. Tôi đã thử nghiệm điều này phần nào với dĩa song song; nguồn đó, một tệp thực hiện và các bài kiểm tra nằm trong một tarball ở đây:
http://cognitivingissonance.ca/cogware/utf8_colorize/utf8_colorize.tar.bz2
Nếu ứng dụng bạn sử dụng với nhật ký lỗi này, hãy nhớ chuyển hướng đó:
application 2>&1 | utf8-colorize -1 2 &
Các tệp .sh trong thư mục thử nghiệm chứa một số ví dụ sử dụng.