暂无图片
暂无图片
1
暂无图片
暂无图片
暂无图片

有用的linux文本工具使用技巧

原创 听见风的声音 2025-04-10
227

现下,多数生产系统的数据库都运行在linux操作系统下,熟练使用liunx各种工具有助于提高工作效率,本文记录了我在工作中使用的linux文本工具小技巧,供各位墨友参考。

1 文本生成技巧

[root@iZuf6b1znamggglbunalhzZ ~]# for i in $(seq 1 10);do echo $i >>test.txt;done; [root@iZuf6b1znamggglbunalhzZ ~]# cat test.txt 1 2 3 4 5 6 7 8 9 10

上面的脚本用的是for循环,seq命令打印一个数字序列,这个脚本,是不是可以写得更简单一点,当然可以,不用for循环,直接写成seq 1 10 testtxt 结果也是一样的,
linux bshell的写法非常灵活这个for循环也可以写成另一种形式

for i in `seq 1 10`;do echo $i >>test.txt; done;

里面可以换成其它shell命令,比如换成ls -l

[root@iZ2ze0t8khaprrpfvmevjiZ ~]# for i in `ls `; do echo $i ;done; my_oss mysql-5.7.34-linux-glibc2.12-x86_64.tar.gz oracle-database-ee-21c-1.0-1.ol8.x86_64.rpm oracle-database-preinstall-21c-1.0-1.el8.x86_64.rpm

这里的for循环用的是列表形式,for循环里的循环体可以写的得更复杂一下,比如在前面和后面加上一些字符串

[root@iZ2ze0t8khaprrpfvmevjiZ ~]# for i in $(seq 1 10);do echo test $i":this is test1" >>test.txt;done; [root@iZ2ze0t8khaprrpfvmevjiZ ~]# cat test.txt test 1:this is test1 test 2:this is test1 test 3:this is test1 test 4:this is test1 test 5:this is test1 test 6:this is test1 test 7:this is test1 test 8:this is test1 test 9:this is test1 test 10:this is test1

2 文本显示技巧

显示行号

linux下最常用的文本显示工具是cat和more,这两个工具使用比较简单,但也有一些平时不为人注意的选项,比如cat 的-n选项可以在每行的左边显示行号

[root@iZuf6b1znamggglbunalhzZ ~]# cat -n /var/log/messages|head -10 1 Nov 30 15:31:43 iZuf6b1znamggglbunalhzZ systemd: Unit rsyslog.service entered failed state. 2 Nov 30 15:31:43 iZuf6b1znamggglbunalhzZ systemd: rsyslog.service failed. 3 Nov 30 15:31:43 iZuf6b1znamggglbunalhzZ systemd: Stopped Dump dmesg to /var/log/dmesg. 4 Nov 30 15:31:43 iZuf6b1znamggglbunalhzZ systemd: Stopping Session 2 of user root. 5 Nov 30 15:31:43 iZuf6b1znamggglbunalhzZ systemd: Stopped target Timers.
从第n页开始分页显示

如果文件太大了,一页显示不下,就要用到more命令,这个命令每次显示一页,按下空格键显示下一页,这个命令也有一些比较实用的使用技巧,例如想从第20行开始显示文件,可以用下面的命令

[root@iZuf6b1znamggglbunalhzZ ~]# more +20 /var/log/messages Nov 30 15:31:43 iZuf6b1znamggglbunalhzZ systemd: Stopping Command Scheduler... Nov 30 15:31:43 iZuf6b1znamggglbunalhzZ systemd: Stopping NTP client/server... Nov 30 15:31:43 iZuf6b1znamggglbunalhzZ systemd: Stopping OpenSSH server daemon... Nov 30 15:31:43 iZuf6b1znamggglbunalhzZ systemd: Stopping Job spooling tools...

显示文件开头几行用head命令,下面的命令显示文件开头的5行

[root@iZuf6b1znamggglbunalhzZ ~]# head -5 /etc/passwd root:x:0:0:root:/root:/bin/bash bin:x:1:1:bin:/bin:/sbin/nologin daemon:x:2:2:daemon:/sbin:/sbin/nologin adm:x:3:4:adm:/var/adm:/sbin/nologin lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
显示文件的末尾几行并跟踪文件变化

显示末尾的几行用tail命令,这个命令除了显示末尾的几行文件外,用-f选项还可以持续跟踪文件的变化,比如下面的命令显示文件最后10行,当文件有新行加入时会显示新加入的行

[root@iZuf6b1znamggglbunalhzZ ~]# tail -f -n 10 /var/log/messages Jul 15 14:53:33 iZuf6b1znamggglbunalhzZ systemd-logind: Removed session 44. Jul 15 14:53:54 iZuf6b1znamggglbunalhzZ systemd: Started Session 45 of user root. Jul 15 14:53:54 iZuf6b1znamggglbunalhzZ systemd-logind: New session 45 of user root. Jul 15 14:53:54 iZuf6b1znamggglbunalhzZ systemd-logind: Removed session 45. Jul 15 14:53:55 iZuf6b1znamggglbunalhzZ systemd: Started Session 46 of user root. Jul 15 14:53:55 iZuf6b1znamggglbunalhzZ systemd-logind: New session 46 of user root. Jul 15 14:53:55 iZuf6b1znamggglbunalhzZ systemd-logind: Removed session 46. Jul 15 14:53:56 iZuf6b1znamggglbunalhzZ systemd: Started Session 47 of user root. Jul 15 14:53:56 iZuf6b1znamggglbunalhzZ systemd-logind: New session 47 of user root. Jul 15 14:53:56 iZuf6b1znamggglbunalhzZ systemd-logind: Removed session 47. Jul 15 14:54:40 iZuf6b1znamggglbunalhzZ systemd: Started Session 48 of user root. Jul 15 14:54:40 iZuf6b1znamggglbunalhzZ systemd-logind: New session 48 of user root. Jul 15 14:54:40 iZuf6b1znamggglbunalhzZ systemd-logind: Removed session 48. Jul 15 14:54:41 iZuf6b1znamggglbunalhzZ systemd: Started Session 49 of user root.

统计文本文件的行数、列数、字符数、字节数用wc命令

[root@iZ2ze0t8khaprrpfvmevjiZ ~]# wc /etc/passwd 33 70 1733 /etc/passwd

第一列33是文件的行数,第二列70是文件的单词数,单词是以空格为分隔符的,第三列1733是字符数或者字节数单独查看行数用-l选项,单词数用-w选项,字符数用-m选项,字节数用-c选项,比如显示文件行数:

[root@iZuf6b1znamggglbunalhzZ ~]# wc -l /etc/passwd 21 /etc/passwd
查看文件编码格式

用file命令可以看到文件的编码格式、文件的类型

[root@iZuf6b1znamggglbunalhzZ ~]# file /var/log/messages /var/log/messages: UTF-8 Unicode text, with very long lines

3 文本查找工具

grep命令查找并显示字符所在的行,比如要想知道ssh服务监听的端口,可以查找ssh配置文件中Port所在的行,这里的P要大写

[root@iZuf6b1znamggglbunalhzZ ~]# grep Port /etc/ssh/ssh_config # Port 22

Port所在的行默认是被注释掉的,此时,ssh使用的是默认的22端口,如果要知道Port在ssh配置文件的第几行,使用-n选项,

[root@iZuf6b1znamggglbunalhzZ ~]# grep -n Port /etc/ssh/ssh_config 41:# Port 22

grep 的-c选项显示所查找的字符串在文件中出现的行数

[root@iZuf6b1znamggglbunalhzZ ~]# grep -c localhost /etc/hosts 2

grep的-v选项用来排除字符所在的行,这个选项常用来在显示进程时排除grep本身,比如查看sshd进程信息

[root@iZuf6b1znamggglbunalhzZ ~]# ps -ef | grep sshd root 1099 1 0 14:41 ? 00:00:00 /usr/sbin/sshd -D root 1389 1099 0 14:42 ? 00:00:00 sshd: root@pts/0 root 2202 1408 0 15:00 pts/0 00:00:00 grep --color=auto sshd [root@iZuf6b1znamggglbunalhzZ ~]# ps -ef | grep -v grep | grep sshd root 1099 1 0 14:41 ? 00:00:00 /usr/sbin/sshd -D root 1389 1099 0 14:42 ? 00:00:00 sshd: root@pts/0 使用了-v选项后,命令的输出不再显示grep进程,排除了grep进程的干扰,输出的结果更容易理解,看起来也更一致,在脚本编程时经常用到。grep也提供-r选项,在目录及其子目录的所有文件中搜索特定字符串 ```bash [root@iZuf6b1znamggglbunalhzZ ~]# grep -r *.sh /etc Binary file /etc/udev/hwdb.bin matches /etc/NetworkManager/dispatcher.d/11-dhclient: for f in $ETCDIR/dhclient.d/*.sh; do /etc/bashrc: for i in /etc/profile.d/*.sh; do /etc/profile:for i in /etc/profile.d/*.sh /etc/profile.d/sh.local ; do

如果要搜索的字符串比较复杂,中间由空格或者特殊字符,就将其放到单引号内,单引号内也可以写正则表达式,如下面这个例子匹配ntp1…,ntp2…,…等,这列的单引号也可以改成双引号,效果是一样的

[root@iZuf6b1znamggglbunalhzZ ~]# grep 'ntp[0-4].aliyun.com' /etc/ntp.conf restrict ntp1.aliyun.com nomodify notrap nopeer noquery restrict ntp2.aliyun.com nomodify notrap nopeer noquery restrict ntp3.aliyun.com nomodify notrap nopeer noquery restrict ntp4.aliyun.com nomodify notrap nopeer noquery

4 文本编辑sed

sed是Linux系统中常用的流编辑器,sed这个名称是stream editor的缩写,这是一个面向行处理的工具,它以“行”为处理单位,针对每一行进行处理,处理后的结果会输出到标准输出,
这里用前面创建的test.txt文件来演示这个工具的几个用法,sed命令的格式是[address]action/argument/flags,地址用来选择操作的行,action是要做的操作,如新增、替换等,第三部分是操作的参数,不同的操作需要不同的参数,flags可以
表示操作的范围,比如经常可以看到的g参数,表示全部的意思,会对整行中所有匹配的内容进行操作,比如

删除指定行
[root@iZ2ze0t8khaprrpfvmevjiZ ~]# sed '3,5d' test.txt
     test 1:this is test1
     test 2:this is test1
     test 6:this is test1
     test 7:this is test1
     test 8:this is test1
     test 9:this is test1
     test 10:this is test1

上面命令中d命令是删除的信息,sed删除了文件中3至5行,将其输出到标准输出,也可用$通配符,匹配至文件结尾

删除至行尾
[root@iZ2ze0t8khaprrpfvmevjiZ ~]# sed '3,$d' test.txt test 1:this is test1 test 2:this is test1

sed删除了第三行至文件结尾,只保留了前两行数据

新增一行

a命令用来新增一行,下面的命令在文件的末尾增加一行,增加行的内容就是a后面的字符串。

[root@iZuf6b1znamggglbunalhzZ ~]# sed '$a admin:x:1000:1000:admin:/home/admin:/bin/bash' /etc/passwd root:x:0:0:root:/root:/bin/bash bin:x:1:1:bin:/bin:/sbin/nologin daemon:x:2:2:daemon:/sbin:/sbin/nologin admin:x:1000:1000:admin:/home/admin:/bin/bash
行内替换

s命令用于在一行内做字符串替换,比如我们在安装linux操作系统后,根据安全的需要经常要做打开和关闭selinux,如果需要这个操作在系统重启后依然生效,需要编辑/etc/selinux/config文件,更改selinux值,最简单的办法是用vi打开这个文件,编辑一下存盘,高效一点的办法是用sed的s命令给,查找到配置问价中selinux的行,将disabled值替换为enforing,用-i选项可以直接编辑文件。

[root@iZuf6b1znamggglbunalhzZ ~]# sed 's/SELINUX=disabled/SELINUX=enforcing/' /etc/selinux/config # This file controls the state of SELinux on the system. # SELINUX= can take one of these three values: # enforcing - SELinux security policy is enforced. # permissive - SELinux prints warnings instead of enforcing. # disabled - No SELinux policy is loaded. SELINUX=enforcing # SELINUXTYPE= can take one of three values: # targeted - Targeted processes are protected, # minimum - Modification of targeted policy. Only selected processes are protected. # mls - Multi Level Security protection. SELINUXTYPE=targeted
改变整行内容

c操作用于改变一行的内容,比如下面的命令将改变了第一行的内容,c 后面的字符串是改变后的内容

[root@iZuf6b1znamggglbunalhzZ ~]# sed '1c abcdefg' /etc/passwd abcdefg bin:x:1:1:bin:/bin:/sbin/nologin daemon:x:2:2:daemon:/sbin:/sbin/nologin adm:x:3:4:adm:/var/adm:/sbin/nologin lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin

5 AWK工具

AWK是一种Linux中处理文本文件的语言,具有强大的文本分析功能,它的名字来源于三位创始人 Alfred Aho,Peter Weinberger, 和 Brian Kernighan ,分别取了三位创始人的姓的首字符,和grep、sed一起被称为linux中三剑客之,三剑客之首就是 AWK。

基本使用方法

awk可以对文本中特定列进行操作,经常用来打印文本中的特定列,比如我们在shell编程时经常需要获得某一网络接口的ip地址,先用ifconfig命令看一下网络接口信息

[root@iZ2ze0t8khaprrpfvmevjiZ ~]# ifconfig lo lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536 inet 127.0.0.1 netmask 255.0.0.0 inet6 ::1 prefixlen 128 scopeid 0x10<host> loop txqueuelen 1000 (Local Loopback) RX packets 103285 bytes 6961676 (6.6 MiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 103285 bytes 6961676 (6.6 MiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 用awk获取接口的ip地址,awk的命令写在单引号内,最简单的命令像下面这样,第一部分是匹配模式,用来查找要操作的行,第二部分是{}内是要执行的操作,这里是打印第二列,$n是AWK的内置变量,$0表示所有列,其它的表示第n列。 ```bash [root@iZ2ze0t8khaprrpfvmevjiZ ~]# ifconfig lo|awk '/inet 1/{print $2}' 127.0.0.1

在linux文件系统中,root(/)文件系统是非常重要的,root文件系统满了,会造成操作系统和软件故障,使用下面的命令可以查看linux root文件系统的剩余空间

[root@iZ2ze0t8khaprrpfvmevjiZ ~]# df -h |awk '/\/$/{print $4}' 22G

上面的awk命令中,匹配模式是///,/,配置一行的结尾,\为转义符,取消后面紧跟的/的特殊含义,这个配置模式的意思就是匹配以/结尾的行,看一下df -h的输出,有利于我们理解这个匹配模式,

[root@iZ2ze0t8khaprrpfvmevjiZ ~]# df -h Filesystem Size Used Avail Use% Mounted on devtmpfs 891M 0 891M 0% /dev tmpfs 909M 476M 433M 53% /dev/shm tmpfs 909M 484K 908M 1% /run tmpfs 909M 0 909M 0% /sys/fs/cgroup /dev/vda3 40G 19G 22G 47% / /dev/vda2 100M 7.3M 93M 8% /boot/efi tmpfs 182M 0 182M 0% /run/user/0

在df -h的输出中,只有root文件系统是以’/’结尾的,匹配到之后,打印第四行及时就是root文件系统的剩余空间,如果要显示结果更友好一点,也可以拼接一下字符串

[root@iZ2ze0t8khaprrpfvmevjiZ ~]# df -h |awk '/\/$/{print "root filesystem left space is "$4}' root filesystem left space is 22G
设置列分隔符

awk的默认列分隔符是空格,也个可以设置为别的分隔符。例如,有的企业一般要求在linux系统中,自定义用户的id要大于1000,在这种情况下用户id<1000的基本都是系统内置用户,如何查询系统中的内置用户的数量,用下面的命令

[root@iZuf6b1znamggglbunalhzZ ~]# awk -F: '$3<1000{x++} END{print x}' /etc/passwd 21

上面的命令中,-F设置分隔符,在这里我们不使用默认的空格作为分隔符,而是使用“:”作为分隔符,文件的第三列是用户id,只要第三列的值小于1000,x(起始值为0)就加一,文件扫描结束时,打印x值,就是文件中所有用户id小于1000的用户的数量。
我们创建linux用户时,经常需要取消执行shell命令的权限,把用户的shell只是为nologin,比如mysql用户,这样可以提高安全性,怎样取出系统中有执行命令权限的用户,用下面的命令:

[root@iZuf6b1znamggglbunalhzZ ~]# awk -F: '$7!~/nologin$/{print $1,$7}' /etc/passwd root /bin/bash sync /bin/sync shutdown /sbin/shutdown halt /sbin/halt

同样要设置分隔符为“:”,,只要第七列不以“nologin”结尾,我们就打印第一列和第7列。下面这个例子没有什么实用价值,只是演示一下awk的格式化输出和文本文件分析能里,我们打印出/etc/password的前三行的名字和uid,并且打印出行数

[root@iZuf6b1znamggglbunalhzZ ~]# head -3 /etc/passwd | awk 'BEGIN{FS=":";print "name\tuid"}{print $1,"\t"$3}END{print "sum lines "NR}' name uid root 0 bin 1 daemon 2 sum lines 3

命令用到awk的begin、end结构,begin后面紧跟的处理开始的动作,在这里,我们打印出列头name和uid,\t是tab键,后面的动作应用到文本处理过程中,打印出第1列和第三列,这两列之间也用tab键分隔,文本处理结束后进行的操作是打印一个汇总行,NR是AWK内置变量,表示处理的行数。

进阶用法-数组的使用

awk可以定义并使用数组,比如一台linux服务器,如果我们想知道它上面处于不同状态的tcp的数量怎么做,如果不用脚本,也可以手工处理,运行一下netstat -na命令,看一下tcp连接的状态,统计一下每种状态下连接的数量,这个需求也用下面的脚本也可以实现

[root@iZuf6b1znamggglbunalhzZ ~]# netstat -na | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}' LISTEN 1 ESTABLISHED 2 TIME_WAIT 1

这个脚本有几个awk中比较高级的用法,需要解释一下,命令中的匹配模式是/^tcp/ ,即匹配以tcp开头的行,$NF是AWK的内置变量,表示行的最后一列,看一下netstat -na中以tcp开头的行最后一列是什么

[root@iZ2ze0t8khaprrpfvmevjiZ ~]# netstat -na|grep tcp tcp 0 0 0.0.0.0:111 0.0.0.0:* LISTEN tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN tcp 0 64 172.20.11.244:22 112.224.4.86:47071 ESTABLISHED tcp 0 0 172.20.11.244:56566 100.100.30.26:80 ESTABLISHED tcp 0 0 172.20.11.244:60892 100.100.18.120:443 TIME_WAIT

可以看到,最后一列正是连接的状态,S[$NF]定义一个数组,这个数组的元素是S[LISTEN], S[ESTABLISHED]等,数组元素的初始值是0,在文本的处理过程中,如果匹配到行,就将数组元素S[连接状态]的值加1,整个文本处理完后,输出数组内的每一个元素及其值。

联合其它工具使用

awk和其它脚本命令组合起来,看一实现一些比较复杂的操作,比如杀掉一组进程

[root@iZuf6b1znamggglbunalhzZ ~]# ps -ef | grep httpd | awk {'print $2'} | xargs kill -9

6 一个有用的脚本

下面这个脚本用awk语言编写,可以用来分析oracle osw 的iostat日志,显示IO等待时间超过特定值的时间和条目

echo time await r_await w_await awk '{ if (/([0-9]{2}):([0-9]{2}):([0-9]{2})/ ) { while ((getline tmp) > 0 ) if (tmp !~ /([0-9]{2}):([0-9]{2}):([0-9]{2})/) { split(tmp,cur_line) if (cur_line[12] > 10 && cur_line[12] ~ /[0-9]+/ ) { print $3,$4,$5,tmp } } else { break } } }' * | awk '$13 > 4 && $5 !~ /\// {print $1,$2,$3,$4," ",$13," ",$14," ",$15}'

将上面的内容保存到一个shell脚本中,放到OSW安装目录archive/oswiostat目录下,命令的输出如下

time device await r_await w_await Jul 26 15:32:49 sda 11.00 0.00 11.00 Jul 26 15:32:49 dm-0 11.00 0.00 11.00 Jul 26 16:39:57 dm-0 15.50 0.00 15.50
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论