FELIX-1744: add a -C/--context option to the grep command
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@824744 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/karaf/shell/commands/src/main/java/org/apache/felix/karaf/shell/commands/GrepAction.java b/karaf/shell/commands/src/main/java/org/apache/felix/karaf/shell/commands/GrepAction.java
index 8241d00..0cfb0c1 100644
--- a/karaf/shell/commands/src/main/java/org/apache/felix/karaf/shell/commands/GrepAction.java
+++ b/karaf/shell/commands/src/main/java/org/apache/felix/karaf/shell/commands/GrepAction.java
@@ -21,6 +21,9 @@
import java.io.IOException;
import java.io.Reader;
import java.io.InputStreamReader;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Queue;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -34,6 +37,12 @@
@Command(scope = "shell", name="grep", description="Prints lines matching the given pattern")
public class GrepAction extends OsgiCommandSupport {
+ public static enum ColorOption {
+ never,
+ always,
+ auto
+ }
+
@Argument(index = 0, name = "pattern", description = "Regular expression", required = true, multiValued = false)
private String regex;
@@ -57,7 +66,31 @@
@Option(name = "-i", aliases = { "--ignore-case" }, description = "Ignores case distinctions in both the PATTERN and the input files.", required = false, multiValued = false)
private boolean ignoreCase;
+ @Option(name = "-c", aliases = { "--count" }, description = "only print a count of matching lines per FILE", required = false, multiValued = false)
+ private boolean count;
+
+ @Option(name = "--color", aliases = { "--colour" }, description = "use markers to distinguish the matching string. WHEN may be `always', `never' or `auto'", required = false, multiValued = false)
+ private ColorOption color = ColorOption.auto;
+
+ @Option(name = "-B", aliases = { "--before-context" }, description = "Print NUM lines of leading context before matching lines. Places a line containing -- between contiguous groups of matches.", required = false, multiValued = false)
+ private int before = -1;
+
+ @Option(name = "-A", aliases = { "--after-context" }, description = "Print NUM lines of trailing context after matching lines. Places a line containing -- between contiguous groups of matches.", required = false, multiValued = false)
+ private int after = -1;
+
+ @Option(name = "-C", aliases = { "--context" }, description = "Print NUM lines of output context. Places a line containing -- between contiguous groups of matches.", required = false, multiValued = false)
+ private int context = 0;
+
+
protected Object doExecute() throws Exception {
+ if (after < 0) {
+ after = context;
+ }
+ if (before < 0) {
+ before = context;
+ }
+ List<String> lines = new ArrayList<String>();
+
String regexp = regex;
if (wordRegexp) {
regexp = "\\b" + regexp + "\\b";
@@ -73,31 +106,74 @@
Pattern p = Pattern.compile(regexp);
Pattern p2 = Pattern.compile(regex);
try {
+ boolean firstPrint = true;
+ int nb = 0;
int lineno = 1;
String line;
+ int lineMatch = 0;
Reader r = new InputStreamReader(System.in);
while ((line = readLine(r)) != null) {
String pattern = ignoreCase ? line.toUpperCase() : line;
if (p.matcher(pattern).matches() ^ invertMatch) {
- if (lineNumber) {
+ if (!count && lineNumber) {
System.out.print(String.format("%6d ", lineno++));
}
Matcher matcher2 = p2.matcher(pattern);
StringBuffer sb = new StringBuffer();
while (matcher2.find()) {
- matcher2.appendReplacement(sb, Ansi.ansi()
- .bg(Ansi.Color.YELLOW)
- .fg(Ansi.Color.BLACK)
- .a(matcher2.group())
- .reset().toString());
+ if (!invertMatch && color != ColorOption.never) {
+ matcher2.appendReplacement(sb, Ansi.ansi()
+ .bg(Ansi.Color.YELLOW)
+ .fg(Ansi.Color.BLACK)
+ .a(matcher2.group())
+ .reset().toString());
+ } else {
+ matcher2.appendReplacement(sb, matcher2.group());
+ }
+ nb++;
}
matcher2.appendTail(sb);
- System.out.println(sb.toString());
+ lines.add(sb.toString());
+ lineMatch = lines.size();
lineno++;
+ } else {
+ if (lineMatch != 0 & lineMatch + after + before <= lines.size()) {
+ if (!count) {
+ if (!firstPrint && before + after > 0) {
+ System.out.println("--");
+ } else {
+ firstPrint = false;
+ }
+ for (int i = 0; i < lineMatch + after; i++) {
+ System.out.println(lines.get(i));
+ }
+ }
+ while (lines.size() > before) {
+ lines.remove(0);
+ }
+ lineMatch = 0;
+ }
+ lines.add(line);
+ while (lineMatch == 0 && lines.size() > before) {
+ lines.remove(0);
+ }
}
}
+ if (!count && lineMatch > 0) {
+ if (!firstPrint && before + after > 0) {
+ System.out.println("--");
+ } else {
+ firstPrint = false;
+ }
+ for (int i = 0; i < lineMatch + after; i++) {
+ System.out.println(lines.get(i));
+ }
+ }
+ if (count) {
+ System.out.println(nb);
+ }
} catch (IOException e) {
}
return null;
@@ -108,7 +184,7 @@
while (true) {
int i = in.read();
if (i == -1 && buf.length() == 0) {
- throw new IOException("break");
+ return null;
}
if (i == -1 || i == '\n' || i == '\r') {
return buf.toString();