linux环境下查找包含指定内容的文件及其所在行数

前言

在linux系统下搜索文件一般情况下一个命令就搞定了,之前搜索文件的时候一直使用find,今天排查问题时想查一个函数的调用者在哪个文件中,发现不会写了,搜了一下发现使用grep命令就可以实现,改变了我对grep命令的理解,原来使用grep命令的情况通常是作为结果的过滤函数,比如ps aux | grep gameserver,这次发现他居然还可以直接用来搜索,其实也是过滤的一种。

使用方法

这里直接给出命令的写法,简单替换搜索内容就可以使用,也方便自己后续查找使用(例如查找包含stream的文件):

1
grep -rn 'stream' . --include='*.cpp'

命令解析

上述命令是一种比较常用的写法,就是在当前目录下(一定要注意那个.)查找包含stream的文件,并显示其所在的行,搜索的文件类型是.cpp,其实--include=后面的内容是遵循glob语法的,详细的就不展开了,简单来说就是支持通配符,而查找选项-rn中的r表示递归查找,其中的n表示显示行号,此外还可以使用选项-i表示忽略大小写,下面简单展示一下3个选项的功能:

  1. -r:只递归查找不显示行号

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    [albert@localhost#18:17:41#/home/albert/test]$grep -r 'stream' . --include='*.cpp'
    ./testPtr.cpp:#include <iostream>
    ./crab-server/code/main/crab.cpp:#include <iostream>
    ./testConstructor.cpp:#include <iostream>
    ./smartptr/auto_ptr.cpp:#include <iostream>
    ./io.cpp:#include <fstream>
    ./io.cpp: ofstream logfile("./logs/players_distribution.txt", ios::out);
    ./ptr.cpp:#include <iostream>
    ./gdbtest/main.cpp:#include <iostream>
    ./test_t.cpp:#include <iostream>
    ./testshareptr.cpp:#include <iostream>
  2. -rn:递归查找并显示行号

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    [albert@localhost#18:17:48#/home/albert/test]$grep -rn 'stream' . --include='*.cpp'
    ./testPtr.cpp:4:#include <iostream>
    ./crab-server/code/main/crab.cpp:3:#include <iostream>
    ./testConstructor.cpp:1:#include <iostream>
    ./smartptr/auto_ptr.cpp:4:#include <iostream>
    ./io.cpp:1:#include <fstream>
    ./io.cpp:9: ofstream logfile("./logs/players_distribution.txt", ios::out);
    ./ptr.cpp:4:#include <iostream>
    ./gdbtest/main.cpp:1:#include <iostream>
    ./test_t.cpp:1:#include <iostream>
    ./testshareptr.cpp:4:#include <iostream>
  3. -rni:递归查找显示行号并且忽略大小写

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    [albert@localhost#18:17:53#/home/albert/test]$grep -rni 'stream' . --include='*.cpp'
    ./testPtr.cpp:4:#include <iostream>
    ./crab-server/code/main/crab.cpp:3:#include <iostream>
    ./testConstructor.cpp:1:#include <iostream>
    ./epoll_cs_demo/testfd.cpp:5: int listen_fd = socket(AF_INET, SOCK_STREAM, 0);
    ./epoll_cs_demo/testfd.cpp:8: listen_fd = socket(AF_INET, SOCK_STREAM, 0);
    ./epoll_cs_demo/testfd.cpp:11: listen_fd = socket(AF_INET, SOCK_STREAM, 0);
    ./epoll_cs_demo/testfd.cpp:14: listen_fd = socket(AF_INET, SOCK_STREAM, 0);
    ./epoll_cs_demo/testfd.cpp:21: listen_fd = socket(AF_INET, SOCK_STREAM, 0);
    ./epoll_cs_demo/testfd.cpp:25: listen_fd = socket(AF_INET, SOCK_STREAM, 0);
    ./epoll_cs_demo/client.cpp:18: int client_fd = socket(AF_INET, SOCK_STREAM, 0);
    ./epoll_cs_demo/server.cpp:24: int listen_fd = socket(AF_INET, SOCK_STREAM, 0);
    ./smartptr/auto_ptr.cpp:4:#include <iostream>
    ./io.cpp:1:#include <fstream>
    ./io.cpp:9: ofstream logfile("./logs/players_distribution.txt", ios::out);
    ./network/zgetaddrinfo.cpp:37: hints.ai_socktype = SOCK_STREAM;/* Stream socket */
    ./linux_version/client.cpp:15: int client_fd = socket(AF_INET, SOCK_STREAM, 0);
    ./linux_version/server.cpp:15: int listen_fd = socket(AF_INET, SOCK_STREAM, 0);
    ./ptr.cpp:4:#include <iostream>
    ./gdbtest/main.cpp:1:#include <iostream>
    ./test_t.cpp:1:#include <iostream>
    ./testshareptr.cpp:4:#include <iostream>

总结

  1. 查找指定内容的简单命令:grep -rn 'stream' . --include='*.cpp'
  2. 这个grep有很多附加的参数,看了文档之后发现了一个点,原来用法:egrepgrep -Efgreprep -F,但是 egrepfgrep现在都不建议使用了,无论是man手册还是--help选项中都提到了这一点
Albert Shi wechat
欢迎您扫一扫上面的微信公众号,订阅我的博客