I am trying to do some grep-like printing, see below.
#define RED "\033[0;31m"
#define GREEN "\033[0;32m"
#define BLUE "\033[0;34m"
#define END "\033[0m"
void print_matches(const string& text, const string& pattern,
const vector<int>& occurrences)
{
const int M = occurrences.size();
const int T = text.size();
const int P = pattern.size();
int i = 0, k = 0, line = 1;
int start_of_line = 0;
while (k < M && i < T) {
if (i == occurrences[k]) { // print the whole line
// follow color scheme of grep
cout << GREEN << line << END << BLUE << ':' << END;
for (int j = start_of_line; j != i; ++j)
cout << text[j];
// add i < T in case of noeol
while (i < T && text[i] != '\n') {
if (i == occurrences[k]) {
cout << RED; // highlight matches
for (int t = 0; t < P; ++t)
cout << text[i++];
cout << END;
++k;
}
else {
cout << text[i++];
}
}
cout << '\n';
}
if (text[i] == '\n') {
++line;
start_of_line = i + 1;
}
++i;
}
}
But I found a problem when redirecting the results to a output file. It also preserves the control chars.
$ printf "\033[0;31mhowdy\n" > tmp # so does this
There're post-processing solutions, for example, see here. But I don't want to write a script to do that. I want it to work the way grep is (redirecting colored output text without control chars). How can I modify the code to make it behave like grep?
PS: I read the manual page of grep and I found an environment variable GREP_COLORS that can change the color of the matched strings on the terminal. Should I use some environment
variables and how? (I am a newbie to the UNIX/Linux environment programming, so if there're anything I didn't make clear, please point out; or help me edit, which would be truly appreciated :)