阅读 82

Java实现Linux grep命令,快速搜索目录下文件中内容

用过Linux的人对grep命令都不会陌生,在面试的时候,如果一个说他会Linux,但是不会grep,基本不会有太好的结果。

在我平时的工作中,grep经常被用于:

  • 查看进程,Linux标准输出过滤
  • 统计功能,grep配合其它命令,如awk
  • 文件内容过滤,查看一个目录下有那个文件包含了指定的内容。比如这个目录下那个文件中包含艾贺

之前写过:Grep使用方法](www.jianshu.com/p/92df6f8fd…),感兴趣可以阅读

grep虽好,但其主要用在Linux上,可能windows上有其它的替代品,不过目前还没有去寻找。灵机一动,这个用Java实现不是也很简单吗?

查看进程,统计,在Windows上用的比较少,但是文件内容过滤在Window上有需要,下面主要说下如何实现文件内容过滤。

需求:查看目录下包含某个内容的文件,及其所在的具体行内容

之前写过:

这里我们采用Java8的Files配合流式编程。

public class GrepDemo {
    public static void main(String[] args) throws IOException {
        String path = "/Users/aihe/Documents/user-426671-1579310873";
        String world = "代码";
        Map<Path, List<String>> map = new HashMap<>();
        grep(path, world, map);
        for (Map.Entry<Path, List<String>> pathListEntry : map.entrySet()) {
            System.out.println(pathListEntry.getKey());
            for (String s : pathListEntry.getValue()) {
                System.out.println(s);
            }
            System.out.println("\n\n");
        }

    }


    /**
     * 查看目录下包含某个内容的文件,及其所在的具体行具体内容,结果保存在map中
     *
     * @param path
     * @param map
     */
    private static void grep(String path, String searchWorld, Map<Path, List<String>> map) throws IOException {

        // 遍历文件
        Files.walk(Paths.get(path))
                .filter(p -> Files.isRegularFile(p))
                // 进行处理
                .filter(p -> {
                    // 可以提取为一个函数
                    try {
                        return Files.readAllLines(p)
                                .stream()
                                .anyMatch(s -> {
                                    // 可以采用正则匹配:
                                    // 参考:https://www.jianshu.com/p/eec9bd411391
                                    boolean contains = s.contains(searchWorld);
                                    if (contains) {
                                        map.computeIfAbsent(p, k -> new LinkedList<>());
                                        map.get(p).add(s);
                                    }
                                    return contains;
                                });
                    } catch (IOException e) {
                        return false;
                    }
                })
                .count();
    }
}

复制代码

结果,目前对过滤到的内容需要手工高亮

image-20200121070834213

主要写法就是这样了。

最后

实在是有些献丑. 如果大家有好的意见和想法,欢迎指出。

然后:

阿里陶系技术部招人,目前大把机会,HC众多,成功率高,流程快,可辅导修改简历,技术答疑,速来... 没事加个朋友也可以 发我邮箱:aihe.ah@alibaba-inc.com 加我微信:aihehe5211