4.1 grep:文本过滤工具

4.1.1 命令详解

【命令星级】 ★★★★★

【功能说明】

grep命令是Linux系统中最重要的命令之一,其功能是从文本文件或管道数据流中筛选匹配的行及数据,如果配合正则表达式技术一起使用,则功能会更加强大,它是Linux运维人员要掌握的命令之一!

grep过滤就相当于是一个筛子,有可能筛子里面的东西是要保留的,也有可能是筛出来的需要保留,grep功能的生活形象图解如图4-1所示。

grep过滤文本内容中末尾是否有空格_bash

图4-1 grep对应生活中的形象工具–筛子

【语法格式】

grep命令里面的匹配模式,都是你要获取的内容,它们既可以是普通的文字符号也可以是正则表达式,其语法格式如图4-2所示。

grep过滤文本内容中末尾是否有空格_linux_02


图4-2 grep命令的语法结构图

【选项参数】

表4-1是grep命令的常用参数说明。

表4-1 grep的常用参数

grep过滤文本内容中末尾是否有空格_bash_03

4.1.2 使用范例

4.1.2.1 基础范例

**范例4-1:**请使用grep过滤不包含neteagle字符串的行(-v参数实战)。

[root@centos7 ~]# cat >test1.txt<<EOF	#创建测试的文件。
> test
> liyao
> neteagle
> EOF
[root@centos7 ~]# grep -v "neteagle" test1.txt	#过滤不包含neteagle字符串的行,注意被过滤的字符串,应尽可能使用双引号。
test
liyao

**提示:**grep -v 参数的作用是排除,默认是以行为单位排除包含参数后面所接内容的某些行。

**范例4-2:**使用grep命令显示过滤后的内容的行号(-n参数实践)。

[root@centos7 ~]# cat >test2.txt<<EOF	#创建测试文件
> lisir
> neteagle
> neteagle linux
> ALEX
> EOF
[root@centos7 ~]# grep -n "neteagle" test2.txt	#输出包含neteagle字符串的行,并显示行号。
2:neteagle
3:neteagle linux
[root@centos7 ~]# grep -n "." test2.txt	#显示所有航的行号(类似于cat -n test2.txt),这里的“.”代表匹配任意单个字符,即匹配了所有得内容,所以,显示了所有行的行号。
1:lisir
2:neteagle
3:neteagle linux
4:ALEX

提示:-n参数会为grep命令找到内容在开头加上对应的行号。

范例4-3:-i不区分大小写参数实战。

[root@centos7 ~]# grep "alex" test2.txt 	#过滤小写alex的行,结果没有内容。
[root@centos7 ~]# grep -i "alex" test2.txt 	#使用-i参数不区分大小写过滤alex。
ALEX

**范例4-4:**同时过滤两个不同的字符串并为过滤的内容显示颜色(-E和–color的参数实践)。

[root@centos7 ~]# \grep -Ei "neteagle|alex" test2.txt	#不区分大小写,同时过滤包含neteagle和alex字符串。 
neteagle
neteagle linux
ALEX
[root@centos7 ~]# \grep -Ei --color=auto "neteagle|alex" test2.txt 	#增加--color参数
neteagle
neteagle linux
ALEX
#匹配的字符串会显示红色颜色。

[root@centos7 ~]# alias grep
alias grep='grep --color=auto'
#因为系统已经把grep设置了别名,为了看到--color参数效果,把前面命令加了“\”转义。

**范例4-5:**计算匹配的字符串的数量(-c参数实践)。

[root@centos7 ~]# grep "neteagle" test2.txt #-c计算出文本中有几个neteagle字符串。
neteagle
neteagle linux
[root@centos7 ~]# grep -c "neteagle" test2.txt
2

**范例4-6:**只输出匹配的内容(-o参数实践)。

[root@centos7 ~]# grep -o "neteagle" test2.txt
neteagle
neteagle

**范例4-7:**利用grep搜索符合要求的用户(-w参数实践)。

准备测试数据:

[root@centos7 ~]# useradd neteagle
[root@centos7 ~]# useradd neteagle1
[root@centos7 ~]# useradd neteagle2
[root@centos7 ~]# grep -w neteagle /etc/passwd	#使用-w搜索neteagle字符串。
neteagle:x:1001:1001::/home/neteagle:/bin/bash
[root@centos7 ~]# grep neteagle /etc/passwd	#如果取消-w参数,则会搜索到包含neteagle字符串的用户。
neteagle:x:1001:1001::/home/neteagle:/bin/bash
neteagle1:x:1002:1002::/home/neteagle1:/bin/bash
neteagle2:x:1003:1003::/home/neteagle2:/bin/bash
4.1.2.2 生产案例

**范例4-8:**去除配置文件里面的注释和空行(正则表达式应用)。

[root@centos7 ~]# yum install -y nginx

[root@centos7 ~]# cat /etc/nginx/nginx.conf
# For more information on configuration, see:
#   * Official English Documentation: http://nginx.org/en/docs/
#   * Official Russian Documentation: http://nginx.org/ru/docs/

user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;

# Load dynamic modules. See /usr/share/doc/nginx/README.dynamic.
include /usr/share/nginx/modules/*.conf;

events {
    worker_connections 1024;
}

http {
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile            on;
    tcp_nopush          on;
    tcp_nodelay         on;
    keepalive_timeout   65;
    types_hash_max_size 2048;

    include             /etc/nginx/mime.types;
    default_type        application/octet-stream;

    # Load modular configuration files from the /etc/nginx/conf.d directory.
    # See http://nginx.org/en/docs/ngx_core_module.html#include
    # for more information.
    include /etc/nginx/conf.d/*.conf;

    server {
        listen       80 default_server;
        listen       [::]:80 default_server;
        server_name  _;
        root         /usr/share/nginx/html;

        # Load configuration files for the default server block.
        include /etc/nginx/default.d/*.conf;

        location / {
        }

        error_page 404 /404.html;
        location = /404.html {
        }

        error_page 500 502 503 504 /50x.html;
        location = /50x.html {
        }
    }

# Settings for a TLS enabled server.
#
#    server {
#        listen       443 ssl http2 default_server;
#        listen       [::]:443 ssl http2 default_server;
#        server_name  _;
#        root         /usr/share/nginx/html;
#
#        ssl_certificate "/etc/pki/nginx/server.crt";
#        ssl_certificate_key "/etc/pki/nginx/private/server.key";
#        ssl_session_cache shared:SSL:1m;
#        ssl_session_timeout  10m;
#        ssl_ciphers HIGH:!aNULL:!MD5;
#        ssl_prefer_server_ciphers on;
#
#        # Load configuration files for the default server block.
#        include /etc/nginx/default.d/*.conf;
#
#        location / {
#        }
#
#        error_page 404 /404.html;
#        location = /404.html {
#        }
#
#        error_page 500 502 503 504 /50x.html;
#        location = /50x.html {
#        }
#    }

}


[root@centos7 ~]# grep -Ev "^$|#" /etc/nginx/nginx.conf		#表示过滤空行,是正则表达式的内容。
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;
include /usr/share/nginx/modules/*.conf;
events {
    worker_connections 1024;
}
http {
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';
    access_log  /var/log/nginx/access.log  main;
    sendfile            on;
    tcp_nopush          on;
    tcp_nodelay         on;
    keepalive_timeout   65;
    types_hash_max_size 2048;
    include             /etc/nginx/mime.types;
    default_type        application/octet-stream;
    include /etc/nginx/conf.d/*.conf;
    server {
        listen       80 default_server;
        listen       [::]:80 default_server;
        server_name  _;
        root         /usr/share/nginx/html;
        include /etc/nginx/default.d/*.conf;
        location / {
        }
        error_page 404 /404.html;
        location = /404.html {
        }
        error_page 500 502 503 504 /50x.html;
        location = /50x.html {
        }
    }
}

说明:

“|”表示或,“^KaTeX parse error: Expected 'EOF', got '#' at position 8: ”表示空行,“#̲”是nginx.conf里面的…\|#”匹配空行或包含注释的行。

**范例4-9:**企业中管理openvpn授权文件的脚本案例(-w实践)。

[root@centos7 ~]# cat add-vpn-user.sh 
#!/bin/bash
#create by neteagle qq 19661891
#time 2020-10-24_15:52:48
# Source function library.
. /etc/init.d/functions
#config file path
FILE_PATH=/etc/openvpn/authfile.conf
[ ! -f $FILE_PATH ] && mkdir -p $FILE_PATH;
usage(){
	cat <<EOF
	USAGE: `basename $0` {-add|-del|-search} username
EOF
}

#judge run user
if [ $UID -ne 0 ] ;then
	echo "You are not supper user,please call root!"
	exit 1;
fi

#judge arg numbers.
if [ $# -ne 2 ] ;then
	usage
	exit
fi

RETVAL=0
case "$1" in
	-a|-add)
		shift
		if grep -w "$1" ${FILE_PATH} >>/dev/null 2>&1;then	#使用-w过滤仅含有指定字符串的用户。
			action $"vpnuser,$1 is exist" /bin/false
			exit
		else
			chattr -i ${FILE_PATH}
			/bin/cp ${FILE_PATH} ${FILE_PATH}.$(date +%F%T)
			echo "$1" >> ${FILE_PATH}
			[ $? -eq 0 ] && action $"Add $1" /bin/true
			chattr +i ${FILE_PATH}
		fi
		;;
	-d|-del)
		shift
		if [ `grep -w "$1" ${FILE_PATH}|wc -l` -lt 1 ];then	#使用-w过滤仅含有指定字符串的用户。
			action $"vpnuser,%1 is not exist." /bin/false
			exit
		else
			chattr -i ${FILE_PATH}
			/bin/cp ${FILE_PATH} ${FILE_PATH}.$(date +%F%T)
			sed -i "/^${1}/d" ${FILE_PATH}
			[ $? -eq 0 ] && action "Del $1" /bin/true
			chattr +i ${FILE_PATH}
			exit
		fi
		;;
	-s|-search)
		shift
		if [ `grep -w "$1" ${FILE_PATH}|wc -l` -lt 1 ];then	#使用-w过滤仅含有指定字符串的用户。
			echo $"vpnuser,$1 is not exist.";exit
		else
			echo $"vpnuser,$1 is exist.";exit
		fi
		;;
	*)
		usage
		exit
		;;
esac