l11.Linux文件过滤及内容编辑处理(一)

985 阅读13分钟

“ 本文正在参加「金石计划 . 瓜分6万现金大奖」 ”

7.1 vi/vim:纯文本编辑器

Windows下最基本的文本编辑器就是记事本,当然还有一些功能强大的文本编辑器,例如notepad++、emeditor等,如果与Linux系统向比较,那么你会发现Windows下的记事本对应的就是Linux里的vi命令,而notepad++、emeditor这样的编辑器对应则是vim命令,因此,掌握vi/vim命令是学好Linux的重要的必修课之一,因为这两个命令是管理Linux必不可少的工具。

7.1.1 命令详解

【命令星级】 ★★★★★

【功能说明】

vi是Linux命令行界面下的重要文字编辑器。vim是vi命令的增强版,例如,高亮显示代码、自动缩进等。vim与vi编辑器是兼容的,建议读者多用vim编辑器替代vi编辑器。

【用法格式】

vim [option] [file]
vim [选项] [文件]

【vim的三种模式】

vim分为三种模式:普通模式、编辑模式、命令模式,其作用分别如下。

(1)普通模式

用vim命令打开一个文件后,默认的状态就是普通模式。在这个模式中,不能进行编辑输入操作,但可以按“上下左右”键来移动光标,同时还可以执行一些操作命令进行如删除、复制、粘贴等工作。

(2)编辑模式

在普通模式下不能进行编辑输入操作,只有按下"i、I、o、O、a、A、r、R、s、S"(其中“i”最为常用)等字母进入编辑模式后才可以执行录入文字等编辑操作。确定文件是否处于编辑模式状态有一个重要的特征,那即是在窗口的左下角要有插入的标记“--INSERT--”或“--插入--”,如图7-1所示。

t7-1.png

图7-1 vim编辑模式

(3)命令模式

在普通模式下,输入":"或“/”或“?”时,光标会自动定位在那一行,在这个模式中,可以执行保存、退出、搜索、替换、显示行号等相关操作。

图7-2所示的是vim的三种模式转换示意图。

t7-2.png

图7-2 vim的三种模式转换示意图

【选项说明】

表7-1针对vi/vim命令的参数选项进行了说明。

表7-1 vi/vim命令的参数选项及说明

b7-1-1.png

b7-1-2.png

7.1.2 使用范例

范例7-1: 进入普通模式。

[root@centos7 ~]# vim oldboy_new.txt

输入“vim 文件名”即可直接进入vim窗口。如图7-3所示,左下角会显示这个文件的当前状态。如果是新文件,则会显示[New File],如“oldboy_new.txt”[New File]。

t7-3.png

图7-3 vim编辑新文件窗口底部

如果是已存在的文件,则会显示当前文件名、行数、字符数等,如图7-4所示。

t7-4.png

图7-4 vim编辑已有文件窗口底部

范例7-2: 进入编辑模式。

在普通模式下,按下i键就可以进入编辑模式,此时可输入任意文本内容。当然还有很多字母也可以实现同样的功能,如"i、I、o、O、a、A、r、R、s、S",从图7-5中可以看到,其左下角有一个“--INSERT--”,表示可以编辑内容了。

t7-5.png

图7-5 vim编辑模式窗口

范例7-3: 按[Esc]键切回到普通模式。

编辑完内容后,可按[Esc]键退出编辑模式,进入普通模式,此时,细心的读者可以从图7-6中注意到窗口左下角的“--INSERT--”消失了。

t7-6.png

图7-6 vim从编辑模式返回普通模式窗口

范例7-4:使用命令模式保存文件内容,退出vim编辑器。

切回到普通模式后,此时就可以使用命令模式保存文件内容了,如图7-7所示,输入“:wq”(保存退出)或“:wq!”(强制保存退出)后敲下回车键即可保存退出。

t7-7.png

图7-7 vim命令模式保存文件窗口底部

7.1.3 通过vim命令打开文件的小结

以下列举几种通过vim命令打开文件的方法。

  • vim file:打开/新建文件,光标置于第一行行首,file为任意文件名。

  • vim file+n:打开文件,光标置于第n行行首,n为自然数。

  • vim file+:打开文件,光标置于最后一行行首。

  • vim file+/pattern:将光标置于与pattern匹配的第一个字符串处,pattern为任意字符串。

    有关vi/vim的命令深入知识(含vim配置及编程开发配置)讲解,可以参考《跟老男孩学Linux运维:Shell编程实战》一书的第16章。

7.2 echo:显示输出文本内容

7.2.1 命令详解

【命令星级】 ★★★★★

【功能说明】

echo命令能将指定文本显示在Linux命令行上,或者通过重定向符写入到指定的文件中。

【语法格式】

echo [option] [string]
echo [选项] [文本]

【选项说明】

表7-2针对echo命令的参数选项进行了说明。

表7-2 echo命令的参数选项及说明

b7-2.png

7.2.2 使用范例

范例7-5: 打印文本到屏幕输出。

[root@centos7 ~]# echo Hello world  #echo直接接想输出的文本。
Hello world
[root@centos7 ~]# echo 'Hello world'    #可以使用单引号将内容括起来。
Hello world
[root@centos7 ~]# echo "Hello world"    #也可以使用双引号。
Hello world
[root@centos7 ~]# echo -e "Hello\tworld"    #使用选项-e可以识别\t(一个tab)等特殊字符。
Hello   world

范例7-6: 将单行文本追加到某个文件中。

[root@centos7 ~]# echo "Hello world" >>hello.txt    #使用追加重定向符号>>将文本写入文件。
[root@centos7 ~]# cat hello.txt
Hello world

范例7-7: 使用-n参数的示例。

[root@centos7 ~]# echo "hello";echo "world" #分别可以连接2个命令。
hello
world
#命令执行结果分成了两行输出。
[root@centos7 ~]# echo -n "hello";echo "world"  #使用-n选项就可以不换行,输出成一行。
helloworld

范例7-8: 打印彩色输出。

命令如下:

[root@centos7 ~]# echo -e "\033[30m 黑色字Hello world \033[0m"
 黑色字Hello world 
[root@centos7 ~]# echo -e "\033[31m 红色字Hello world \033[0m"
 红色字Hello world 
[root@centos7 ~]# echo -e "\033[32m 绿色字Hello world \033[0m"
 绿色字Hello world 
[root@centos7 ~]# echo -e "\033[33m 黄色字Hello world \033[0m"
 黄色字Hello world 
[root@centos7 ~]# echo -e "\033[34m 蓝色字Hello world \033[0m"
 蓝色字Hello world 
[root@centos7 ~]# echo -e "\033[35m 紫色字Hello world \033[0m"
 紫色字Hello world 
[root@centos7 ~]# echo -e "\033[36m 天蓝字Hello world \033[0m"
 天蓝字Hello world 
[root@centos7 ~]# echo -e "\033[37m 白色字Hello world \033[0m"
 白色字Hello world

提示: 上文加粗的递增数字表示字体颜色范围。

图7-8为打印效果图。

t7-8.png

图7-8 打印彩色输出效果图

假设要打印的背景色的数字范围为40-47,命令如下:

[root@centos7 ~]# echo -e "\033[40;37m 黑底白字Welcome to Red1Hat\033[0m"
 黑底白字Welcome to Red1Hat
[root@centos7 ~]# echo -e "\033[41;37m 红底白字Welcome to Red2Hat\033[0m"
 红底白字Welcome to Red2Hat
[root@centos7 ~]# echo -e "\033[42;37m 绿底白字Welcome to Red3Hat\033[0m"
 绿底白字Welcome to Red3Hat
[root@centos7 ~]# echo -e "\033[43;37m 黄底白字Welcome to Red4Hat\033[0m"
 黄底白字Welcome to Red4Hat
[root@centos7 ~]# echo -e "\033[44;37m 蓝底白字Welcome to Red5Hat\033[0m"
 蓝底白字Welcome to Red5Hat
[root@centos7 ~]# echo -e "\033[45;37m 紫底白字Welcome to Red6Hat\033[0m"
 紫底白字Welcome to Red6Hat
[root@centos7 ~]# echo -e "\033[46;37m 天蓝白字Welcome to Red7Hat\033[0m"
 天蓝白字Welcome to Red7Hat
[root@centos7 ~]# echo -e "\033[47;30m 白底黑字Welcome to Red8Hat\033[0m"
 白底黑字Welcome to Red8Hat

提示: 上文加粗的递增数字表示背景颜色范围。

图7-9为打印的效果图。

t7-9.png

图7-9 打印彩色背景色效果图

有关字体颜色内容,在《跟老男孩学Linux运维:Shell编程实战》一书的第9章有详细介绍。

范例7-9: 打印变量内容。

[root@centos7 ~]# echo $PATH        #打印环境变量,在环境变量名前面使用“$”符号。
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
[root@centos7 ~]# test=12345
[root@centos7 ~]# echo $test
12345

提示: 与echo类似的命令还有printf,这是一个功能更强的输出命令,具体请见后文。

7.3 cat:合并文件或查看文件内容

7.3.1 命令详解

【命令星级】 ★★★★★

【功能说明】

cat命令可以理解为英文单词concatenate的缩写,其功能是连接多个文件并且打印到屏幕输出,或者重定向到指定文件中。此命令常用于显示单个文件内容,或者将几个文件内容连接起来一起显示,还可以从标准输入中读取内容并显示,生产环境中,它常与重定向或追加符号配合使用。

cat命令的记忆方法:cat的中文意思是猫,可以理解为“瞄”一下文件内容,那就是显示文件内容了。根据笔者的运维经验,cat具备5大常用功能,具体请见表7-3。

表7-3 cat命令常用功能

b7-3.png

【语法格式】

cat [option] [file]
cat [选项] [文件]

说明:在cat命令及后面的选项和文件里,每个元素之间都至少要有一个空格。

【选项说明】

表7-4针对cat命令的参数选项进行了说明。

表7-4 cat命令的参数选项及说明

b7-4.png

7.3.2 使用示例

7.3.2.1 基础范例

范例7-10: 执行cat的完整命令生产test.txt文件内容。

方法1:

[root@centos7 ~]# cat >test.txt<<EOF
> welcome to Linux
>
> if you like Linux please support me
>
>
>
> bye! boys and girls
> EOF   #这里要敲回车才能结束,另外,EOF必须成对出现,但也可以用别的成对标签进行替换。例如:neteagle字符标签,默认情况下结尾的EOF必须要顶格写。

方法2:

[root@centos7 ~]# cat >test.txt<<-EOF   #如果cat后面使用了“<<-”符号,则结尾的EOF可以不用顶格,但是要用tab键缩进。
>welcome to Linux
>
>if you like Linux please support me
>
>
>
>bye! boys and girls
> EOF

以上就是cat命令在生产环境中常用的非交互式编辑文件的方法,请不用忽略上下文中的恐慌,那是下文测试选项时需要用到的。另外,如果内容中包含$符号时要用“\”符号进行转义。

以上命令的执行结果如下:

[root@centos7 ~]# cat >test.txt<<EOF                                     
> welcome to Linux
> 
> if you like Linux please support me
> 
> 
> 
> bye! boys and girls
> EOF
[root@centos7 ~]# cat test.txt 
welcome to Linux
#此行是空行。
if you like Linux please support me
#此行是空行。
#此行是空行。
#此行是空行。
bye! boys and girls

范例7-11: 直接执行cat命令查看文件内容,不带任何选项。

[root@centos7 ~]# cat test.txt 
welcome to Linux
​
if you like Linux please support me
​
​
​
bye! boys and girls

这就是最简单最基本的查看文件内容的使用方法了。

范例7-12: 执行cat命令,分别带-n及-b选项,并对比两者的区别。

[root@centos7 ~]# cat -n test.txt 
     1  welcome to Linux
     2  
     3  if you like Linux please support me
     4  
     5  
     6  
     7  bye! boys and girls
#说明:从上面的例子中可以看出,“-n”选项就是执行为文件内容编号并打印输出,包括空行。
[root@centos7 ~]# cat -b test.txt 
     1  welcome to Linux
​
     2  if you like Linux please support me
​
​
​
     3  bye! boys and girls
# 说明:从上面的例子中可以看出,-b选项与-n选项类似,但是-b选项并不为空行编号。    

范例7-13: 执行cat命令,带-E选项。

[root@centos7 ~]# cat -E test.txt 
welcome to Linux$
$
if you like Linux please support me$
$
$
$
bye! boys and girls$

从上面的例子可以看出,-E选项就是将文件结尾的隐藏结束标识符$符显示出来。即使是空行,结尾也是有结束标识符的,这一点大家需要注意。

再来个小例子:

[root@centos7 ~]# cp test.txt test1.txt
[root@centos7 ~]# echo >test1.txt 
[root@centos7 ~]# cat -E test1.txt 
$
[root@centos7 ~]# ll test1.txt 
-rw-r--r--. 1 root root 1 Oct  9 14:13 test1.txt

这个小例子更好地说明了即使是空行结尾也是有标识符$的。因此,在计算文件占用空间时,要注意这点。

-A(-vET)、-e(-vE)这两个选项都包含-E选项,因此,有与-E类似的功能,但-v、-T这两个选项在工作中使用得不多,了解一下即可。

范例7-14: 执行cat命令,带-s选项。

[root@centos7 ~]# cat -s test.txt 
welcome to Linux
​
if you like Linux please support me
#此处原来是3行空行,现在,由于-s选项的原因,变成了一个空行了。
bye! boys and girls

从上面的例子可以看出,-s选项就是将两个以上的空行变成一个空行,如果文件中连续的空行很多,那么这个选项可以让文件显示更加精炼易读。

但是在实际生产工作中,我们还是习惯使用grep -v "^$" test.txt过滤掉所有的空行(一个空行都不留),从而让显示更紧凑一些,示例代码如下。有关grep的讲解,详见后文。

[root@centos7 ~]# grep -v "^$" test.txt #"^$"是正则表达式字符组合,表示空行。
welcome to Linux
if you like Linux please support me
bye! boys and girls

范例7-15: 执行cat命令编辑新文件。

[root@centos7 ~]# cat >test3.txt
hi,here is Linux os.
^C
[root@centos7 ~]# cat test3.txt
hi,here is Linux os.

从上面的例子可以看出,这里是利用cat和“>”重定向将标准输出定向到文件,这是一张特殊的编辑文件的方法。

这里有几个问题需要注意一下,具体如下:

1)结束标记可以用快捷键Ctrl+d或Ctrl+c退出,但是必须要先执行回车操作,将光标定位到新的末输入的行才行。

2)利用此种方式输入时,会发现如果输入错了,只按退格键(Backspace)将无法删除,需要按住“Ctrl+退格键”才能删除。

3)此操作是一种特殊编辑方法,此处仅作为扩展知识点提及,生产环境中使用得很少。

范例7-16: 执行cat命令连接并显示多个文件。

[root@centos7 ~]# cat test.txt test3.txt 
welcome to Linux
​
if you like Linux please support me
​
​
​
bye! boys and girls #此行以上是test.txt 的内容。
hi,here is Linux os.    #这是test3.txt的内容。

提示: 这样两个文件会一起显示,但还是会有先后顺序之分的,前面的test.txt的内容会优先显示。

7.3.2.2 生产案例

说明:后面的生产案例会涉及Shell编程相关知识,如果没有Shell编程功底,则只需关注cat命令的用法即可。

范例7-17: 利用cat实现一键优化Linux系统脚本。

这是使用cat命令实现非交互式地在文件结尾增加内容的功能。下面的优化脚本是批量修改配置文件的方法,是生产环境中经常用到的用法,要熟练掌握才好。

下面以一键优化脚本中的一部分Linux服务器内核选项优化为例来说明cat的功能。

说明:本优化适合Apache、Nginx、Squid等多种Web相关应用,特殊的业务可能需要略做调整。

所谓内核优化,主要是在Linux系统中针对业务服务应用而进行的系统内核选项优化,优化并无特殊的标准,下面以常见的生产换 中Linux的内核优化为例进行讲解,仅供大家参考。示例代码如下: 所谓内核优化,主要是在Linux系统中针对业务服务应用而进行的系统内核选项优化,优化并无特殊的标准,下面以常见的生产换 中Linux的内核优化为例进行讲解,仅供大家参考。示例代码如下:

[root@centos7 ~]# vim opt_sysctl.sh
#!/bin/bash
​
/bin/cp /etc/sysctl.conf /etc/sysctl.conf.`date +%F_%T`
#备份sysctl.conf
​
cat >>/etc/sysctl.conf<<EOF #修改sysctl.conf。
#added by neteagle at 2020 start
net.ipv4.tcp_fin_timeout = 2
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_keepalive_time = 600
net.ipv4.ip_local_port_range = 4000 65000
net.ipv4.tcp_max_syn_backlog = 16384
net.ipv4.tcp_max_tw_backets = 36000
net.ipv4.route.gc_timeout = 100
net.ipv4.tcp_syn_retries = 1
net.ipv4.tcp_synack_retries = 1
net.core.somaxconn = 16384
net.ipv4.netdev_max_backlog = 16384
net.ipv4.tcp_max_orphans = 16384
#end
EOF
sysctl -p &>/dev/null   #加载sysctl.conf。
:wq

以上是脚本内容,下面是执行情况:

[root@centos7 ~]# sh opt_sysctl.sh
[root@centos7 ~]# tail -16 /etc/sysctl.conf
#added by neteagle at 2020 start
net.ipv4.tcp_fin_timeout = 2
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_keepalive_time = 600
net.ipv4.ip_local_port_range = 4000 65000
net.ipv4.tcp_max_syn_backlog = 16384
net.ipv4.tcp_max_tw_backets = 36000
net.ipv4.route.gc_timeout = 100
net.ipv4.tcp_syn_retries = 1
net.ipv4.tcp_synack_retries = 1
net.core.somaxconn = 16384
net.ipv4.netdev_max_backlog = 16384
net.ipv4.tcp_max_orphans = 16384
#end

注意: EOF可以使用任意成对字符串来代替,通常习惯使用EOF。

范例7-18: 利用cat在脚本中显示帮助菜单。

[root@centos7 ~]# vim exportfs_usage.sh
#/bin/bashexportfs_usage()
{
    cat <<END
    USAGE: $0 {start|stop|monitor|status|validate-all}
END
}
exportfs_usage
:wq

执行上述脚本后的效果:

[root@centos7 ~]# sh exportfs_usage.sh 
    USAGE: exportfs_usage.sh {start|stop|monitor|status|validate-all}

这里的cat命令可以用echo命令来代替,对于单行的内容显示和追加内容,使用echo命令是非常合适的,cat的优势是针对多行文本内容进行编辑,或者在已有内容的结尾追加新内容。

范例7-19: 利用cat在脚本中显示内容选择菜单。

[root@centos7 ~]# vim menu.sh
#/bin/bash
​
menu(){
    cat <<END
    1.[apple]
    2.[pear]
    3.[banana]
    4.[cherry]
    5.[orange]
    please select one that you like:
END
}
menu
:wq

执行上述脚本后的效果如下:

[root@centos7 ~]# sh menu.sh
    1.[apple]
    2.[pear]
    3.[banana]
    4.[cherry]
    5.[orange]
    please select one that you like:

为了实现自动化运维,有时高级运维人员不得不通过脚本将操作写好,然后让组内的初级运维或非运维的同事,通过傻瓜式的餐单选择,来完成相应的工作,进而提升工作效率。

上面的脚本,从美感的角度来看,还是有缺陷。比如:

[root@centos7 ~]# vim menu.sh
#/bin/bash
​
menu(){
        cat <<END
        1.[apple]
        2.[pear]
        3.[banana]
        4.[cherry]
        5.[orange]
        please select one that you like:
        END #此处定格写,没有保持队列。但是直接保持队列,脚本执行又会报错。
}
menu
[root@centos7 ~]# sh menu.sh
menu.sh: line 13: warning: here-document at line 4 delimited by end-of-file (wanted `END')
menu.sh: line 14: syntax error: unexpected end of file

改进后的脚本如下:

[root@centos7 ~]# vim menu.sh
#/bin/bash
​
menu(){
    cat <<-END  #此处END前加了一个减号。
    1.[apple]
    2.[pear]
    3.[banana]
    4.[cherry]
    5.[orange]
    please select one that you like:
    END #因为前面使用了“-END”,因此此处可以使用Tab键缩进,记住是以Tab键缩进而不是空格!
}
menu
:wq

7.4 more:分页显示文件内容

7.4.1 命令详解

【命令星级】 ★★★★★

【功能说明】

more命令的功能类似于cat,但cat命令是将整个文件的内容一次性的显示在屏幕上,而more则会一页一页地显示文件内容。但more的功能还是比较简单的,其有一个增强版的命令是less,将在7.5节详细讲解。

【语法格式】

more [option] [file]
more [选项] [文件]

说明: 在more命令及后面的选项和文件里,每个元素直接都至少要有一个空格。

【选项说明】

表7-5针对more命令的参数选项进行了说明。

表7-5 more命令的参数选项及说明

b7-5.png

在交互模式下,使用more命令打开文本后,会进入一个基于vi的交互界面,在这里可以使用部分vi编辑器的功能,如搜索功能,还可以切换到vi编辑器。表7-6给出了more命令的交互式子命令。

表7-6 more命令的交互式子命令及说明

b7-6.png

7.4.2 使用范例

7.4.2.1 基础范例

范例7-20: 执行more命令,后面不接任何参数。

[root@centos7 ~]# more /etc/services    #若不接任何参数,则会满屏显示文件内容。
# /etc/services:
# $Id: services,v 1.55 2013/04/14 ovasik Exp $
#
# Network services, Internet style
# IANA services version: last updated 2013-04-10
#
# Note that it is presently the policy of IANA to assign a single well-kn
own
# port number for both TCP and UDP; hence, most entries here have two ent
ries
# even if the protocol doesn't support UDP operations.
# Updated from RFC 1700, ``Assigned Numbers'' (October 1994).  Not all po
rts
# are included, only the more common ones.
#
# The latest IANA port assignments can be gotten from
#       http://www.iana.org/assignments/port-numbers
# The Well Known Ports are those from 0 through 1023.
# The Registered Ports are those from 1024 through 49151
# The Dynamic and/or Private Ports are those from 49152 through 65535
#
# Each line describes one service, and is of the form:
#
# service-name  port/protocol  [aliases ...]   [# comment]
​
tcpmux          1/tcp                           # TCP port service multip
--More--(0%)    #还有已经显示内容的百分比。

读者可以在上面的交互界面测试一下常用的交互命令,比如按空格键往下翻一屏,按“b”往上翻一屏,若想要查找“3306”,则先输入一个“/”,然后输入“3306”敲回车即可找到。

范例7-21: 查看前n行。

[root@centos7 ~]# more -5 /etc/services #此时并不是满屏显示文件内容,只会显示5行内容。
# /etc/services:
# $Id: services,v 1.55 2013/04/14 ovasik Exp $
#
# Network services, Internet style
# IANA services version: last updated 2013-04-10
--More--(0%)

范例7-22: 从指定的行数开始显示内容。

[root@centos7 ~]# more +888 /etc/services   #此时直接从第888行显示文件内容。
rescap          283/udp                 # rescap
corerjd         284/tcp                 # corerjd
corerjd         284/udp                 # corerjd
fxp             286/tcp                 # FXP Communication
fxp             286/udp                 # FXP Communication
k-block         287/tcp                 # K-BLOCK
k-block         287/udp                 # K-BLOCK
novastorbakcup  308/tcp                 # Novastor Backup
novastorbakcup  308/udp                 # Novastor Backup
entrusttime     309/tcp                 # EntrustTime
entrusttime     309/udp                 # EntrustTime
bhmds           310/tcp                 #       bhmds
bhmds           310/udp                 #       bhmds
asip-webadmin   311/tcp                 # AppleShare IP WebAdmin
asip-webadmin   311/udp                 # AppleShare IP WebAdmin
vslmp           312/tcp                 # VSLMP
vslmp           312/udp                 # VSLMP
magenta-logic   313/tcp                 # Magenta Logic
magenta-logic   313/udp                 #       Magenta Logic
opalis-robot    314/tcp                 # Opalis Robot
opalis-robot    314/udp                 # Opalis Robot
dpsi            315/tcp                 # DPSI
dpsi            315/udp                 # DPSI
decauth         316/tcp                 # decAuth
decauth         316/udp                 # decAuth
zannet          317/tcp                 # Zannet
--More--(7%)