Linux笔记14-Bash字符串处理

本文详细介绍了Linux系统中用于字符和字段处理的命令,包括cut的字段提取,printf的格式化输出,awk的文本处理,sed的流编辑,以及正则表达式的使用。这些工具在处理文本数据时非常实用,特别是对于日志分析和数据过滤。文章还提供了多个实例来演示如何使用这些命令。
摘要由CSDN通过智能技术生成

目录

字符截取命令

cut字段提取命令

cut命令的局限

printf命令

printf 和 echo 和 cat

在awk命令的输出中支持print和printf命令

awk命令

sed命令

字符处理命令

1、排序命令sort

2、统计命令wc

正则表达式与通配符

基础正则表达式


字符截取命令

cut字段提取命令

[root@localhost ~]# cut [选项] 文件名

选项:

-f 列号: 提取第几列

-d 分隔符: 按照指定分隔符分割列

说明:一般情况下,cut命令都会和管道符 grep 一起使用。

[root@localhost ~]# vi student.txt

ID Name gender Mark
1 Liming M 86
2 Sc M 90
3 Gao M 83

[root@localhost ~]# cut -f 2 student.txt

[root@localhost ~]# cut -f 2,3 student.txt

例如: /etc/passwd 这个文件不是用Tab分割的,而是用:分割的,就要用到 -d

[root@localhost ~]# cut -d ":" -f 1,3

【扩展】提取所有可以登录的用户(原理在于能登陆的都包含字符串“/bin/bash” ,不能登陆的包含“/sbin/nologin”)

假如现在要删除掉不包含root的用户,使用 grep -v 可以取反:

进一步,提取这些用户的用户名,cut命令就用上了:

cut命令的局限

[root@localhost ~]# df -h | cut -d " " -f 1,3

案例:获取sda1的已用的部分(8%)

发现并没有取到想要的 数字 “8”,原因在于这里的间隔不是制表符,而是空格。

那么,如下尝试:

按照空格分隔,提取到的是空白行。

cut命令不能识别空格作为分隔符的字符串,要识别空格作为分隔符的,需要用到awk命令。

但是awk要比cut复杂得多,所以如果能用cut实现的就用cut。

printf命令

printf '输出类型输出格式' 输出内容

输出类型:

%ns: 输出字符串。n是数字指代输出几个字符

%ni: 输出整数。n是数字指代输出几个数字

%m.nf: 输出浮点数。m和n是数字,指代输出的整数位数和小数位数。如%8.2f代表共输出8位数,其中2位是小数,6位是整数。

输出格式:

\a: 输出警告声音

\b: 输出退格键,也就是Backspace键

\f: 清除屏幕

\n: 换行

\r: 回车,也就是Enter键

\t: 水平输出退格键,也就是Tab键

\v: 垂直输出退格键,也就是Tab键

[root@localhost ~]# printf %s 1 2 3 4 5 6

最基本的用法,不做任何处理,当作数字直接输出:

[root@localhost ~]# printf %s %s %s 1 2 3 4 5 6

这样的写法是不符合需求的,会把后面两个“%s”原封输出:

[root@localhost ~]# printf '%s %s %s' 1 2 3 4 5 6

加上引号之后,就会把123当成一组数据,456当成一组数据

[root@localhost ~]# printf '%s %s %s\n' 1 2 3 4 5 6

要加入换行符,使用\n

printf 和 echo 和 cat

用cat 可以查看一个文本的内容,但是printf 呢?

其实只是把文件名当成了一个字符串,要使用printf查看文本内容,需要这样:

printf ‘%s’ $(cat student.txt)

这样就是把文本中的内容连在一起输出,忽略所有格式,类似于遍历字符。

[root@localhost ~]# vi student.txt

ID Name PHP Linux MySQL Average
1 Liming 82 95 86 87.66
2 Sc 74 96 87 85.66
3 Gao 99 83 93 91.66

printf '%s' $(cat student.txt) #不调整输出格式,案例如上。

printf '%s\t %s\t %s\t %s\t %s\t %s\t \n' $(cat student.txt) #调整格式输出

用printf 实现类似cat的格式:

如下:

使用printf 的原因在于:awk命令中不支持cat 和 echo。

在awk命令的输出中支持print和printf命令

print:print会在每个输出之后自动加入一个换行符(Linux默认没有print命令,但是awk中有)

printf:printf是标准格式输出命令,并不会自动加入换行符,如果需要换行,需要手工加入换行符。

awk命令

# awk '条件1{动作1} 条件2{动作2}…' 文件名

条件(Pattern):一般使用关系表达式作为条件,举例如下:

x > 10 判断变量 x是否大于10

x>=10 大于等于

x<=10 小于等于

动作(Action):

格式化输出

流程控制语句

[root@localhost ~]# vi student.txt

ID Name PHP Linux MySQL Average
1 Liming 82 95 86 87.66
2 Sc 74 96 87 85.66
3 Gao 99 83 93 91.66

◆ 输出第二列和第六列,$2表示第二列,$0 表示整个这一行。这里没有任何条件判断。

# awk '{printf $2 "\t" $6 "\n"}' student.txt

df -h 

◆ 使用awk 命令打印df -h 命令的第1、5、6列,注意下面用的是print,可以直接换行。

# df -h | awk '{print $1 "\t" $5 "\t" $6 }'

◆ 实现之前的 获取 sda1的已用的8%的“8”

BEGIN

# awk 'BEGIN{printf "This is a transcript \n" }

{printf $2 "\t" $6 "\n"}' student.txt

END

# awk 'END{printf "The End \n" }

{printf $2 "\t" $6 "\n"}' student.txt

FS内置变量

# cat /etc/passwd | grep "/bin/bash" | \

awk 'BEGIN {FS=":"} {printf $1 "\t" $3 "\n"}'

注意:第一行没有处理!原因是先读取之后才写进分隔符“:”。解决办法:使用BEGIN,在读取前就写进分隔符。

关系运算符

# cat student.txt | grep -v Name | \

awk '$6 >= 87 {printf $2 "\n" }'

案例:打印出第六列大于等于87的Name值:

sed命令

sed 是一种几乎包括在所有 UNIX 平台(包括 Linux)的轻量级流编辑器。sed主要是用来将数据进行选取、替换、删除、新增的命令。

[root@localhost ~]# sed [选项] ‘[动作]’ 文件名

选项:

-n: 一般sed命令会把所有数据都输出到屏幕,如果加入此选择,则只会把经过sed命令处理的行输出到屏幕。

-e: 允许对输入数据应用多条sed命令编辑

-i: 用sed的修改结果直接修改读取数据的文件,而不是由屏幕输出

动作:

a \: 追加,在当前行后添加一行或多行。添加多行时,除最后一行外,每行末尾需要用“\”代表数据未完结。

c \: 行替换,用c后面的字符串替换原数据行,替换多行时,除最后一行外,每行末尾需用“\”代表数据未完结。

i \: 插入,在当前行前面插入一行或多行。插入多行时,除最后一行外,每行末尾需要用“\”代表数据未完结。

d: 删除,删除指定的行。

p: 打印,输出指定的行。

s: 字串替换,用一个字符串替换另外一个字符串。格式为“ 行范围s/旧字串/新字串/g ”(和vim中的替换格式类似)。

学生成绩表

[root@localhost ~]# vi student.txt

ID Name PHP Linux MySQL Average
1 Liming 82 95 86 87.66
2 Sc 74 96 87 85.66
3 Gao 99 83 93 91.66

行数据操作

[root@localhost ~]# sed '2p' student.txt #查看文件的第二行

[root@localhost ~]# sed -n '2p' student.txt #加上 -n,就只输出指定的结果

◆ 获取磁盘信息df -h 的第二行数据:

[root@localhost ~]# sed '2,4d' student.txt #删除第二行到第四行的数据,但不修改文件本身只打印出第一行,但是原文件没有改变。如果要同时改变原文件,就要加上 -i

[root@localhost ~]# sed '2a hello' student.txt #在第二行后追加hello

[root@localhost ~]# sed '2i hello \

world' student.txt #在第二行前插入两行数据

# sed '2c No such person‘ student.txt #替换第二行的数据

【字符串替换】

# sed ‘s/旧字串/新字串/g’ 文件名

# sed '3s/74/99/g' student.txt #在第三行中,把74换成99

#sed -i '3s/74/99/g' student.txt #sed操作的数据直接写入文件,但是没有输出

#sed -e 's/Liming//g ; s/Gao//g' student.txt #同时把“Liming”和“Gao”替换为空

允许多个条件同时执行,使用 -e ,条件之间使用分号。

字符处理命令

1、排序命令sort

[root@localhost ~]# sort [选项] 文件名

选项:

-f: 忽略大小写

-n: 以数值型进行排序,默认使用字符串型排序

-r: 反向排序

-t: 指定分隔符,默认是分隔符是制表符

-k n[,m]: 按照指定的字段范围排序。从第n字段开始,m字段结束(默认到行尾)

[root@localhost ~]# sort /etc/passwd #排序用户信息文件

[root@localhost ~]# sort -r /etc/passwd #反向排序

[root@localhost ~]# sort -t ":" -k 3,3 /etc/passwd #指定分隔符是“:”,用第三字段开头,第三字段结尾排序,就是只用第三字段排序

下面的结果可以看出,并没有按照数字0、1、2、3... 排序,因为默认是当成字母了,而不是数字。

[root@localhost ~]# sort -n -t ":" -k 3,3 /etc/passwd #按照数字排序,加上-n

2、统计命令wc

[root@localhost ~]# wc [选项] 文件名

选项:

-l: 只统计行数

-w: 只统计单词数

-m: 只统计字符数

◆ 统计文件下有多少行、多少个单词、多少个字符:

◆ 只统计指定的

◆ 通过管道符使用


正则表达式与通配符

正则表达式用来在文件中匹配符合条件的字符串,正则是包含匹配。grep、awk、sed等命令可以支持正则表达式。

通配符用来匹配符合条件的文件名,通配符是完全匹配。ls、find、cp这些命令不支持正则表达式,所以只能使用shell自己的通配符来进行匹配了。

【表格内容】元字符 --- 作 用

* 前一个字符匹配0次或任意多次。

. 匹配除了换行符外任意一个字符。

^ 匹配行首。例如:^hello会匹配以hello开头的行。

$ 匹配行尾。例如:hello&会匹配以hello结尾的行。

[] 匹配中括号中指定的任意一个字符,只匹配一个字符。例如:[aoeiu] 匹配任意一个元音字母,[0-9] 匹配任意一位数字, [a-z][0-9]匹配小写字和一位数字构成的两位字符。

[^] 匹配除中括号的字符以外的任意一个字符。例如:[^0-9] 匹配任意一位非数字字符,[^a-z] 表示任意一位非小写字母。

\ 转义符。用于取消讲特殊符号的含义取消。

\{n\} 表示其前面的字符恰好出现n次。例如:[0-9]\{4\} 匹配4位数字,[1][3-8][0-9]\{9\} 匹配手机号码。

\{n,\} 表示其前面的字符出现不小于n次。例如: [0-9]\{2,\} 表示两位及以上的数字。

\{n,m\} 表示其前面的字符至少出现n次,最多出现m次。例如: [a-z]\{6,8\} 匹配6到8位的小写字母。

基础正则表达式

“*”前一个字符匹配0次,或任意多次

grep "a*" test_rule.txt #匹配所有内容,包括空白行

这样其实就是列出整篇文档,没有意义。

grep "aa*" test_rule.txt #匹配至少包含有一个a的行

grep "aaa*" test_rule.txt #匹配最少包含两个连续a的字符串

grep "aaaaa*" test_rule.txt #则会匹配最少包含四个个连续a的字符串

“.” 匹配除了换行符外任意一个字符

grep "s..d" test_rule.txt #“s..d”会匹配在s和d这两个字母之间一定有两个字符的单词

grep "s.*d" test_rule.txt #匹配在s和d字母之间有任意字符

grep ".*" test_rule.txt #匹配所有内容

“^”匹配行首,“$”匹配行尾

grep "^M" test_rule.txt #匹配以大写“M”开头的行

grep "n$" test_rule.txt #匹配以小写“n”结尾的行

grep -n "^$" test_rule.txt #会匹配空白行

 “[]” 匹配中括号中指定的任意一个字符,只匹配一个字符

grep "s[ao]id" test_rule.txt #匹配s和i字母中,要不是a、要不是o

grep "[0-9]" test_rule.txt #匹配任意一个数字

grep "^[a-z]" test_rule.txt #匹配用小写字母开头的行

“[^]” 匹配除中括号的字符以外的任意一个字符

grep "^[^a-z]" test_rule.txt #匹配不用小写字母开头的行

grep "^[^a-zA-Z]" test_rule.txt #匹配不用字母开头的行

 “\” 转义符

grep "\.$" test_rule.txt #匹配使用“.”结尾的行

“\{n\}”表示其前面的字符恰好出现n次

grep "a\{3\}" test_rule.txt #匹配a字母连续出现三次的字符串

grep "[0-9]\{3\}" test_rule.txt #匹配包含连续的三个数字的字符串

“\{n,\}”表示其前面的字符出现不小于n次

grep "^[0-9]\{3,\}[a-z]" test_rule.txt #匹配最少用连续三个数字开头的行

“\{n,m\}”匹配其前面的字符至少出现n次,最多出现m次

grep "sa\{1,3\}i" test_rule.txt #匹配在字母s和字母i之间有最少一个a,最多三个a

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

浮尘笔记

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值