Linux 学习笔记 -- 第三部分 学习 shell 与 shell script -- 第12章 正则表达式与文件格式化处理

本文深入探讨了正则表达式及其在Shell命令中的高级应用,包括使用正则表达式进行文本搜索、过滤、格式化和数据处理的方法。通过实例演示了如何在实践中运用正则表达式进行复杂的文本操作,如筛选特定字符串、查找集合字符、行首与行尾字符匹配、任意字符和重复字符的匹配、限定连续字符范围等。同时,介绍了sed命令的使用,包括其动作参数的功能和以行为单位的新增、删除、替换及显示功能,以及如何利用sed进行数据处理和文件修改。此外,还展示了如何使用diff、cmp、patch进行文件比较和版本控制,以及如何使用pr、find等命令进行文件打印和查找。最后,总结了Shell命令中常用的文件处理技巧和工具,旨在提高用户的Shell编程技能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

-----正则表达式


正则表达式基本上是一种“表示法”,只要工具程序支持这种表示法,那么该工具程序就可以用来作为正则表达式的字符串处理之用。
使用正则表达式时,需要特别留意当时环境的语系为何,否则可能会发现与别人不相同的选取结果。
[]里面不论有几个字符,它都只代表一个字符


dmesg 列出内核信息
wget 下载网络上的文件


高级版 grep
grep:列出包含查询表达式内容的行
-A 后面可加数字,为 after 的意思,除了列出该行外,后续的 n 行也列出来
-B 后面科加数字,为 before 的意思,除了列出该行外,前面的 n 行也列出来
--color=auto 可将正确的那个选取数据列出颜色


dmesg | grep 'eth'

dmesg | grep -n --color=auto 'eth'


dmesg | grep -n -A3 -B2 --color=auto 'eth'

例题一:查找特定字符串

grep -n 'the' regular_express.txt

grep -vn 'the' regular_express.txt (反向)

grep -in 'the' regular_express.txt (忽略大小写)


例题二:利用中括号[]来查找集合字符


grep -n 't[ae]st' regular_express.txt (查找包含tast、test的行)


grep -n 'oo' regular_express.txt (查找包含oo的行)


grep -n '[^g]oo' regular.express.txt (查找包含oo,但oo前面不是g的行)

grep -n '[^a-z]oo' regular_express.txt 
grep -n '[^[:lower:]]oo' regular_express.txt (查找包含oo,但oo前面不是小写英文字母的行)

grep -n '[0-9]' regular_express.txt 
grep -n '[[:digit:]]' regular_express.txt (查找包含数字0-9的行)


例题三:行首与行尾字符^$


grep -n '^the' regular_express.txt (查找行首是the的行)


grep -n '^[a-z]' regular_express.txt 
grep -n '^[[:lower:]]' regular_express.txt (查找行首是小写英文字母的行)


grep -n '^[[^a-zA-Z]]' regular_express.txt (查找开头不是英文字母的行)

^ 符号在字符集合符号(中括号[])之内与之外是不同的,在[]内代表“反向选择”,在[]之外则代表定位在行首


grep -n '\.$' regular_express.txt (查找结尾是 . 的行, \ 代表转义)

grep -n '^$' regular_express.txt (查找空白行)


cat -n /etc/syslong.conf
grep -v '^$' /etc/syslog.conf | grep -v '^#' (查找非空白行与非注释行)


例题四:任意一个字符.与重复字符*

. (小数点):代表一定有一个任意字符的意思
* (星号):代表重复前一个0到无穷多次的意思,为组合形态
.*: 代表0个或多个任意字符


grep -n 'g..d' regular_express.txt (查找包含g??d的行)

grep -n 'oo*' regular_express.txt (查找至少包含1个o的行)


grep -n 'ooo*' regular_express.txt (查找至少包含2个o的行)


grep -n 'goo*g' regular_express.txt (查找包含开头与结尾都是g,中间至少有一个o的内容的行)


grep -n 'g.*g' regular_express.txt (查找包含开头与结尾都是g,中间是任意字符的内容的行)


grep -n '[0-9][0-9]*' regular_express.txt (查找至少包含1个数字的行)


例题五:限定连续RE字符范围{}

因为 { 与 } 的符号在 shell 里是有特殊意义的,所以必须使用转义字符 \ 来让它们失去特殊意义才行


grep -n 'o\{2\}' regular_express.txt (查找包含2个连续o的内容的行)


grep -n 'go\{2,5\}g' regular_express.txt (查找包含开头与结尾都是g,中间是2-5个o的内容的行)


grep -n 'go\{2,\}g' regular_express.txt (查找包含开头与结尾都是g,中间是2到无穷个o的内容的行)


grep -n \' regular_express.txt (查找包含单引号 ' 的行)


set 工具:sed [-nefr] 动作
-n 使用安静模式。在一般 sed 的用法中,所有来自 STDIN 的数据一般都会被列出到屏幕上。但如果加上 -n 参数后,
  则只有经过 sed 处理的那一行(或操作)才会被列出来
-e 直接在命令行模式上进行 sed 的动作编辑
-f 直接将 sed 的动作写在一个文件内, -f filename 则可以执行 filename 内的 sed 动作
-i 直接修改读取的文件内容,而不是由屏幕输出

动作说明:[n1][,n2] function
 
  n1, n2 不一定会存在,一般代表选择进行动作的行数


function 有下面这些参数:

a 新增,a 的后面可以接字符串,而这些字符串会在新的一行出现(目前的下一行)
c 替换,c 的后面可以接字符串,这些字符串可以替换 n1,n2 之间的行
d 删除,因为是删除,所以 d 后面通常不接任何参数
i 插入,i 的后面可以接字符串,而这些字符串会在新的一行出现(目前的上一行)
p 打印,也就是将某个选择的数据打印出来。通常 p 会与参数 sed -n 一起运行
s 替换,可以直接进行替换的工作。通常可以搭配正则表达式!例如 1,20s/old/new/g


以行为单位的新增/删除功能:

nl /etc/passwd | sed '2,5d' (将2-5行删除)
nl /etc/passwd | sed '2d' (将2行删除)
nl /etc/passwd | sed '2,$d' (将2-最后一行删除)


nl /etc/passwd | sed '2a drink tea' (在第2行后加上'drink tea')
nl /etc/passwd | sed '2i drink tea' (在第2行前加上'drink tea')


nl /etc/passwd | sed '2i drink tea or ......\
> drink beer ? ' (在第2行后加上多行内容,行与行之间必须用 \ 分隔开)  

以行为单位的替换与显示功能:

nl /etc/passwd | sed '2,5c No 2-5 number' (将2-5行替换成为"No 2-5 number")

nl /etc/passwd | sed -n '5,7p' (仅列出5-7行)


部分数据的查找并替换功能:

/sbin/ifconfig eth0 | grep 'inet addr' | sed 's/^.*inet addr://g' (删除inet addr:)
/sbin/ifconfig eth0 | grep 'inet addr' | sed 's/^.*inet addr://g' | sed 's/Bcast.*$//g' (再删除Bcast到最后)


  cat /etc/manpath.config | grep 'MAN' | sed 's/#.*$//g' | sed '/^$/d' (只要包含MAN的内容的行,并且不要批注行)

直接修改文件内容:(危险操作)
sed -i 's/\.$/\!/g' regular_express.txt (将每一行结尾的 . 换成 !)
sed -i '$a # This is a test' regular_express.txt (将最后一行加入 "# This is a test")

格式化打印:printf
\a 警告声音输出
\b 退格键 (backspace)
\f 轻触屏幕 (from feed)
\n 输出新的一行
\r 亦即 Enter 按键
\t 水平的 [tab] 按键
\v 垂直的 [tab] 按键
\xNN NN为两位数的数字,可以转换数字成为字符
关于 C 程序语言内,常见的变量格式
%ns 那个 n 是数字, s 代表 string , 即多少个字符
%ni 那个 n 是数字, i 代表 integer,即多少整数字数
%N.nf 那个 n 与 N 都是数字,f 代表 floating (浮点),如果有效数字数,
     假设我共要十个位数,但小数点有两位,即为 %10.2f

printf '%s\t %s\t %s\t %s\t %s\t \n' $(cat printf.txt)

printf '%10s %5i %5i %5i %8.2f \n' $(cat printf.txt | grep -v Name)


printf '\x45\n'


数据处理工具:awk '条件类型 1{动作 1} 条件类型 2{动作 2} ...' filename 
NF 每一行($0)拥有的字段总数
NR 目前 awk 所处理的是"第几行"数据
FS 目前的分隔字符,默认是空格键

last -n 5 | awk '{print $1 "\t" $3}' (取出账号与登陆者的IP,且账号与IP之间以[tab]隔开)

last -n 5 | awk '{print $1 "\t lines: " NR "\t columes: " NF}'


cat /etc/passwd | awk '{FS=":"} $3 < 10 {print $1 "\t" $3}'

cat /etc/passwd | awk 'BEGIN {FS=":"} $3 < 10 {print $1 "\t" $3}'


cat /etc/passwd | awk 'NR==1 {print "%10s %10s %10s %10s %10s\n",$1,$2,$3,$4,"Total" }
NR>=2 {total = $2 + $3 + $4
printf "%10s %10d %10d %10d %10.2f\n", $1, $2, $3, $4, total}'


文件比较工具:
diff [-bBi] from-file to-file 以行为单位进行比较,常用于比较同一文件(或软件)的新旧版本区别上
from-file 一个文件名,作为欲比较文件的文件名
to-file   一个文件名,作为目的比较文件的文件名
注意,from-file 或 to-file 可以用 - 替换,那个 - 代表"standard input"之意


-b 忽略一行当中仅有多个空白的区别(例如"about me"与"about       me"视为相同)
-B 忽略空白行的区别
-i 忽略大小写的不同


mkdir -p /tmp/test
cd /tmp/test
cp /etc/passwd passwd.old
cat /etc/passwd | sed -e '4d' -e '6c no six line' > passwd.new


diff passwd.old passwd.new


diff /etc/rc3.d/ /etc/rc5.d


cmp [-s] file1 file2 以字节进行比较
-s 将所有的不同点的字节处都列出来。因为cmp默认仅会输出第一个发现的不同点。


cmp passwd.old passwd.new


patch 
patch -pN < patch_file  更新
patch -R -pN < patch_file  还原


-p 后面的N表示取消几层目录的意思
-R 代表还原,将新的文件还原成原来旧的版本


diff -Naur passwd.old passwd.new > passwd.patch
cat passwd.patch
patch -p0 < passwd.patch
ll passwd*
patch -R -p0 < passwd.patch
ll passwd*


文件打印 pr filename,标题中会有文件时间、文件名及页码


find / -type f | xargs -n 10 grep '\*' (查找系统中所有文件名以及文件内容中包含*的行)
find / -type f | xargs -n 10 grep -l '\*' (查找系统中所有文件名中包含*的行)


ifconfig eth0 | grep 'inet addr' | sed 's/^.*inet addr://g' | cut -d ' ' -f 1 (查找本机IP)


利用 test 命令的测试功能
source 会在主进程中执行脚本
netstat -tuln 取得主机目前启动的服务
whoami 显示目前的身份
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值