常用文本管理
通配符
用于shell做路径匹配,一般配合find,ls,cp,mv等作文件名匹配
*:匹配任意多个字符
?:匹配一个
[list]:匹配list中任意单个字符
[c1-c2]:匹配c1-c2中任意单个字符
[^c1-c2]/[!c1-c2]:不匹配
{st1,st2....}:匹配任意单个字符串
shell元字符
字符 | 说明 |
---|---|
IFS | 由 |
CR | 由 |
= | 设定变量。 |
$ | 作变量或运算替换 |
> | 重导向 stdout。 |
< | 重导向 stdin。 |
丨 | 命令管线。 |
& | 重导向 file descriptor ,或将命令置于背境执行。 |
( ) | 将其内的命令置于 nested subshell 执行,或用于运算或命令替换。 |
{ } | 将其内的命令置于 non-named function 中执行,或用在变量替换的界定范围。 |
; | 在前一个命令结束时,而忽略其返回值,继续执行下一个命令。 |
&& | 在前一个命令结束时,若返回值为 true,继续执行下一个命令(echo $?如果为0则上一条命令执行成功) |
丨丨 | 在前一个命令结束时,若返回值为 false,继续执行下一个命令。 |
! | 执行 history 列表中的命令。 |
转义
'':硬转义,里面所有的转义都会失效被当作字符串处理
"":软转义,转义会生效
正则
##字符匹配
.:匹配任意单个字符
[]:匹配指定范围内任意单个字符
[^]:匹配指定范围外任意单个字符
[:alnum:]:字母与数字字符
[:alpha:]:字母
[:blank:]:空格或制表符
[:cntrl:]:ASCII控制字符
[:digit:]:数字
[:graph:]:非控制、非空格字符
[:lower:]:小写字母
[:print:]:可打印字符
[:punct:]:标点符号字符
[:space:]:空白字符,包括垂直制表符
[:upper:]:大写字母
[:xdigit:]:十六进制数字
##匹配次数
*:匹配前面的字符任意次数
.*:匹配任意长度的字符
\?:匹配其前面字符0或1次,即前面的可有可无
\+:匹配其前面的字符至少1次
\{m\}:匹配前面的字符m次
\{m,n\}:匹配前面的字符至少m次,至多n次
\{0,n\}:匹配前面的字符至多n次
\{m,\}:匹配前面的字符至少m次
##位置锚定
^:行首锚定,用于模式的最左侧
$:行末锚定,用于模式的最右侧
^PATTERN$:用于模式匹配整行;
^$:空行
\< 或 \b:词首锚定,用于单词模式的左侧
\> 或 \b:词尾锚定,用于单词模式的右侧
\<PATTERN\>:匹配整个单词
##分组
\(\):将一个或多个字符捆绑在一起;当作一个字符
\(xy\)*ab
Note:分组括号中的模式匹配到的内容会被正则表达式引擎记录于内部的变量中,这些变量的命令 方式为:
\1,\2,\3……
\1:从左侧起,第一个左括号以及与之匹配右括号之间的模式所匹配到的字符;
\(ab\+\(xy\)*\):
\1:ab\+\(xy\)*
\2:xy
## 扩展
文本三剑客
find
通过遍历指定路径下文件来完成查找,实时精确,速度略慢
find [ ] [ path] [条件 处理]
find [-H] [-L] [-P] [-Olevel] [-D help|tree|search|stat|rates|opt|exec] [path...] [expression]
按文件名
-name:
-iname:忽略大小写
[root@server1 ~]# find / -iname ens*
按大小
-size +/-大小
[root@server1 ~]# find /etc -size +5M
/etc/udev/hwdb.bin
查找目录深度
-maxdepth n
-mindepth n
[root@server1 ~]# find /etc -maxdepth 3 -a -name *ens*
/etc/pki/tls/openssl.cnf
/etc/sysconfig/network-scripts/ifcfg-ens33
按时间
-mtime +/-n 单位为天
-atime
-ctime
[root@server1 ~]# find /root/ -mtime -3
按属主属组
-user
-group
-nouser:没有属主的文件
-nogroup
按权限
-perm [+/-]MODE
/MODE:任何一类对象的权限只要有一位能匹配即可(如/222)
-MODE:每一类对象都必须同时拥有规定的权限
按组合条件
-a:与
-o:或
-not:非
处理动作
-ls:ls -l
-delete:删除
-fls:查到的所有文件的长格式信息保存到指定文件中
-ok cmd {}\:对查到的每个文件执行cmd并交互确认
-exec cmd {} \:对查到的每一个文件执行cmd
[root@server1 ~]# find /etc -size +5M -ls
17243382 7760 -r--r--r-- 1 root root 7942570 1月 12 10:11 /etc/udev/hwdb.bin
find /etc -mtime -3 -exec cp -r {} test/ \;
grep(配合正则)
-E:扩展正则
-i:忽略大小写
-n:打印行号
-o:只打印匹配的内容
-c:只打印每个文件匹配的行数
-v:只打印不匹配的行
-B:--before--context=NUM:只打印匹配的前几行
-A:--after--context=NUM:打印匹配的后几行
-C:--context=NUM:打印匹配的前后几行
实例
[root@server1 test1]# cat t1
saxcs
#fasc
#fesads
#gfxsd
#234Rfa
2134
342fsd
sdf
hrl
casa
忽略大小写
[root@server1 test1]# grep -i 'r' t1
#234Rfa
hrl
过滤空行
[root@server1 test1]# grep -v "^$" t1
saxcs
#fasc
#fesads
#gfxsd
#234Rfa
2134
342fsd
sdf
hrl
casa
过滤以#开头的行
[root@server1 test1]# grep -v "^#" t1
saxcs
2134
342fsd
sdf
hrl
casa
过滤#开头的行和空行
[root@server1 test1]# grep -Ev "^$|^#" t1
saxcs
2134
342fsd
sdf
hrl
casa
打印包括sa的前两行
[root@server1 test1]# grep -B 2 'sa' t1
saxcs
#fasc
#fesads
--
sdf
hrl
casa
只打印sa
[root@server1 test1]# grep -o 'sa' t1
sa
sa
sa
打印包含sa的行
[root@server1 test1]# grep 'sa' t1
saxcs
#fesads
casa
打印且显示行数
[root@server1 test1]# grep -n 'sa' t1
1:saxcs
3:#fesads
11:casa
正则
1.显示/proc/meminfo文件中以大小s开头的行
grep "^[Ss]" /proc/meminfo
grep -i "^s" /proc/meminfo
2.显示/etc/passwd文件中不以/bin/bash结尾的行
grep -v "/bin/bash$" /etc/passwd
3.如果root用户存在,显示其默认的shell程序 位置锚定
[root@test tmp]# id root > /dev/null && grep "^root\>" /etc/passwd | cut -d: -f7
4.找出/etc/passwd中的两位或三位数
(贪婪)
[[:digit:]]\{2,3\}
(非贪婪)
grep "\<[[:digit:]]\{2,3\}\>" /etc/passwd
5.寻找以字母开头,后面内容中存在数字
grep -i "^[[:alpha:]]\+.*[[:digit:]]\+" 2.txt
6.找出成功连接的
grep "\(200\)\?" 1.log
sed
sed是面向流的编辑器
语法
sed的命令格式: sed [option] 'sed command' filename
sed的脚本格式:sed [option] -f 'sed script' filename
常用选项:
-n :只打印模式匹配的行
-e :直接在命令行模式上进行sed动作编辑,默认选项
-f :将sed的动作写在一个文件内,用–f filename 执行filename内的sed动作
-r :支持扩展表达式
-i :直接修改文件内容 ,很危险不建议这样做
查询文本的方式
使用行号和行号范围
x:行号
x,y:从x行到y行
x,y!:x行到y行之外
/pattern:查询包含模式的行
/pattern/, /pattern/:查询包含两个模式的行
/pattern/,x:x行内查询包含模式的行
x,/pattern/:x行后查询匹配模式的行
动作
p:打印匹配的行(-n)
=:显示文件行号
a\:指定行号后添加新文本
i\:指定行号前添加新文本
d:删除定位行
c\:用新文本替换定位文本
w filename:写文本到一个文件
r filename:从另一个文件读文本
s///:替换
替换标记:
g:行内全局替换
p:显示替换成功的行
w:将替换成功的结果保存至指定文件
q:第一个模式匹配后立即退出
{}:在定位行执行的命令组,用逗号分隔
g:将模式2粘贴到/pattern n/
实例
在第四行后添加一行
[root@server1 test1]# cat t1
one
two
three
four
five
six
[root@server1 test1]# sed 4a\test t1
one
two
three
four
test
five
six
列出passwd文件内容并打印序号,同时删除2-5行
[root@server1 test1]# nl /etc/passwd | sed 2,5d
1 root:x:0:0:root:/root:/bin/bash
6 sync:x:5:0:sync:/sbin:/bin/sync
7 shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
8 halt:x:7:0:halt:/sbin:/sbin/halt
9 mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
10 operator:x:11:0:operator:/root:/sbin/nologin
11 games:x:12:100:games:/usr/games:/sbin/nologin
12 ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
13 nobody:x:99:99:Nobody:/:/sbin/nologin
14 systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin
15 dbus:x:81:81:System message bus:/:/sbin/nologin
16 polkitd:x:999:998:User for polkitd:/:/sbin/nologin
17 sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
18 postfix:x:89:89::/var/spool/postfix:/sbin/nologin
19 chrony:x:998:996::/var/lib/chrony:/sbin/nologin
添加多行文字
[root@server1 test1]# nl t1 | sed '2a hello\
> nihao'
1 one
2 two
hello
nihao
3 three
4 four
5 five
6 six
替换文本
[root@server1 test1]# nl /etc/passwd | sed '2,5c you cant see that'
1 root:x:0:0:root:/root:/bin/bash
you cant see that
6 sync:x:5:0:sync:/sbin:/bin/sync
7 shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
8 halt:x:7:0:halt:/sbin:/sbin/halt
9 mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
10 operator:x:11:0:operator:/root:/sbin/nologin
11 games:x:12:100:games:/usr/games:/sbin/nologin
12 ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
13 nobody:x:99:99:Nobody:/:/sbin/nologin
14 systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin
15 dbus:x:81:81:System message bus:/:/sbin/nologin
16 polkitd:x:999:998:User for polkitd:/:/sbin/nologin
17 sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
18 postfix:x:89:89::/var/spool/postfix:/sbin/nologin
19 chrony:x:998:996::/var/lib/chrony:/sbin/nologin
只打印筛选出的行
[root@server1 test1]# nl t1 | sed -n 1,3p
1 one
2 two
3 three
搜索
[root@server1 test1]# nl /etc/passwd | sed -n "/root/p"
1 root:x:0:0:root:/root:/bin/bash
10 operator:x:11:0:operator:/root:/sbin/nologin
删除查找到的内容并输出其他的
[root@server1 test1]# nl /etc/passwd | sed '/root/d'
2 bin:x:1:1:bin:/bin:/sbin/nologin
3 daemon:x:2:2:daemon:/sbin:/sbin/nologin
4 adm:x:3:4:adm:/var/adm:/sbin/nologin
5 lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
6 sync:x:5:0:sync:/sbin:/bin/sync
7 shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
8 halt:x:7:0:halt:/sbin:/sbin/halt
9 mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
11 games:x:12:100:games:/usr/games:/sbin/nologin
12 ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
13 nobody:x:99:99:Nobody:/:/sbin/nologin
14 systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin
15 dbus:x:81:81:System message bus:/:/sbin/nologin
16 polkitd:x:999:998:User for polkitd:/:/sbin/nologin
17 sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
18 postfix:x:89:89::/var/spool/postfix:/sbin/nologin
19 chrony:x:998:996::/var/lib/chrony:/sbin/nologin
查找后执行花括号里的命令,每个命令用分号分隔,先替换再输出
[root@server1 test1]# nl /etc/passwd | sed '/root/{s/bash/nologin/;p;q}'
1 root:x:0:0:root:/root:/bin/nologin
1 root:x:0:0:root:/root:/bin/nologin
取ip地址
[root@server1 test1]# ifconfig | sed -n '/netmask/p' | sed 's/^.*inet //g' | sed 's/ netmask.*$//g' | sed -n '1p'
192.168.226.148
多项命令
[root@server1 test1]# nl /etc/passwd | sed -e '3,$d' -e 's/bash/blueshell/'
1 root:x:0:0:root:/root:/bin/blueshell
2 bin:x:1:1:bin:/bin:/sbin/nologin
awk
awk能通过简单的脚本来处理文件,一般来说,awk以文件的一行为处理单位,每接收一行就执行相对应的命令.awk只能用单引号
awk '{pattern + action}' {filenames}
-F指定切割符号,不写默认为空格,$n代表分割后的每一个字段,$0代表一整行。一行就是一个记录,一个记录有若干个字段,NF为字段数量,NR为记录数量,RS为记录分隔符,默认为\n
[root@server1 test1]# awk -F: '{print $0}' t1
one:123:312
two:231:431
three:432:5r13
[root@server1 test1]# awk -F: '{print $1}' t1
one
two
three
常用内置变量
变量名 | 属性 |
---|---|
$0 | 当前记录 |
$n | 当前记录的第n个字段 |
FS | 输入分隔符,默认为空格 |
RS | 输入记录分隔符。默认换行符 |
NF | 当前记录的字段个数 |
NR | 当前读出的记录数 |
OFS | 输出字段分隔符,默认空格 |
ORS | 输出记录分隔符,默认换行符 |
awk正则
awk '/REG/{action} ' file
布尔表达式awk '布尔表达式{action}' file
判断、循环、数组
awk提供了类似c语言的部分语句
if
{
if ($1=="foo"){
if($2=="foo"){
print "uno"
}else{
print "one"
}
}elseif($1=="bar"){
print "two"
}else{
print "three"
}
}
while
{
count=1do {
print "I get printed at least once no matter what"
} while ( count !=1 )
}
for
for ( initial assignment; comparison; increment ) {
code block
}
数组
{
cities[1]=”beijing”
cities[2]=”shanghai”
cities[“three”]=”guangzhou”
for( c in cities) {
print cities[c]
}
print cities[1]
print cities[“1”]
print cities[“three”]
}
实例
打印文件的20-30行
[root@server1 test1]# awk '{if(NR >=20 && NR <=30) print $1}' t1
从文本中过滤出姓名和id,以逗号和空格为分隔符,[ ,]+表示空格或者逗号至少出现一次
[root@server1 test1]# awk -F'[ ,]+' '{print $2" "$6}' t1
arisa 123654
统计passwd用户认数(当然此处也可以使用wc -l)
[root@server1 test1]# awk 'BEGIN{line=0}{line++}END{print line}' /etc/passwd
19
#BEGIN和END在开始和结束的时候会执行一次,中间的代码每取出一个记录会执行一次
统计目录下文件的总大小
[root@server1 test1]# ll /root
总用量 4
-rw-------. 1 root root 1241 1月 12 10:11 anaconda-ks.cfg
drwxr-xr-x. 3 root root 29 2月 18 19:48 test
[root@server1 test1]# ll | awk 'BEGIN{size=0}{size +=$5}END{print size} '
30
统计内存占有率大于0.1的进程,并把相关信息保存到文件当中
[root@server1 test1]# ps -aux| grep -v USER|awk '{if($4>0.1)print$2,$11}' > t1
[root@server1 test1]# cat t1
1 /usr/lib/systemd/systemd
3141 /usr/lib/systemd/systemd-journald
3169 /usr/lib/systemd/systemd-udevd
3170 /usr/sbin/lvmetad
6259 /usr/lib/polkit-1/polkitd
6262 /usr/bin/dbus-daemon
6269 /usr/sbin/NetworkManager
6558 /usr/sbin/sshd
6559 /usr/bin/python2
6561 /usr/sbin/rsyslogd
6644 /usr/libexec/postfix/master
6646 qmgr
6827 sshd:
6831 sshd:
6835 -bash
6850 /usr/libexec/openssh/sftp-server
9132 /sbin/dhclient
9315 pickup
取ip
[root@server1 test1]# ifconfig|awk '{if(NR==2)print$2}'
判断服务器上用户的类型
awk -F: '{if($3==0) print"root"}{ if($3>0 && $3< 1000) print"系统用户"}{ if($3>=1000) print"普通用户"}' /etc/passwd
筛选出含有root的行
[root@server1 test1]# awk '/root/{print $0}' /etc/passwd
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
用户为root的行
[root@server1 test1]# awk -F: '$1=="root"{print$0}' /etc/passwd
root:x:0:0:root:/root:/bin/bash
统计/etc/fstab/文件中每个文件类型出现的次数
awk '/^UUID/{fs[$3]++}END{for(i in fs){print i,fs[i]}}' /etc/fstab