Linux shell编程学习笔记3

更新时间:2023-07-25 13:24:01 阅读量: 实用文档 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

shell

Linux shell编程学习笔记(三) --chinaitlab linux学习视频

第五章 文本过滤

1.正则表达式

一种用来描述文本模式的特殊语法,由普通字符以及特殊字符(元字符)组成

^ ----只匹配行首

$ ----只匹配行尾

* ----匹配0个或多个此单字符

[] ----只匹配[]内字符,可以使用-表示序列范围[1-5]

\ ----屏蔽一个元字符的特殊含义

. ----匹配任意单字符

pattern\{n\} 只用来匹配前面pattern出现的次数,n为次数

pattern\{n,\}只用来匹配前面pattern出现的次数,至少为n

pattern\{n,m\}只用来匹配前面pattern出现的次数,次数在n-m之间

eg:

A\{3\}B AAAB

A\{3,\}B AAAB AAAAB ...

A\{3,5\}B AAAB AAAAB AAAAAB

2.find命令 ----查找文件和目录

find pathname -options [-print -exec -ok]

pathname --查找的目录路径. .--表示当前目录,/表示根目录

-print 输出

-exec 对匹配的文件执行该参数所给出的shell命令,相应命令形式为'command'{} \;'意{}和\;之间的空格

-ok 与-exec相同,不过执行命令前会有提示

options :

-name

-perm

-user

-group

-mtime -n +n (atime,-ctime) 修改时间(访问时间,创建时间)

-size n[c]

-type 查找某一类型的文件

eg.

[test@szbirdora 1]$ find ./ -mtime +5

./helloworld.sh

./nohup.out

查看./目录(当前)下修改时间超过5天的文件

3.grep介绍

grep -c 输出匹配行计数

grep -i 不区分大小写

grep -h 查询多文件时不显示文件名 注

shell

grep -H 显示文件名

grep -l 查询多文件时只输出包含匹配字符的文件名

grep -n 显示匹配行及行号

grep -s 不显示不存在或不匹配文本的错误信息

grep -v 显示不包含匹配文本的所有行(过滤文本)

eg.

[test@szbirdora 1]$ grep -n 's.a' myfile

2:/dev/sda1 20G 3.3G 16G 18% /

4:/dev/sda2 79G 18G 58G 23% /u01

5:/dev/sda4 28G 3.9G 22G 15% /u02

[test@szbirdora 1]$ grep -n '2$' myfile

5:/dev/sda4 28G 3.9G 22G 15% /u02

grep -options '正则表达式' filename

4.sed介绍

sed不与初始化文件打交道,它操作的只是一个拷贝,然后所有的改动如果没有重定向到一个文件将输出到屏幕

sed是一种重要的文本过滤工具,使用一行命令或使用管道与grep与awk相结合。 sed调用:

1.命令 sed [options] '正则表达式sedcommand' input-files

2.script :sed [options] -f sedscript input-files

sed在文本中查询文本的方式

-行号,可以是简单数字,或一个行号范围

-使用正则表达式

x ----行号

x,y ----行号范围从x到y

x,y! ---不包含行号x到y

sed命令选项:

-n 不打印

-c 下一个命令是编辑命令

-f 如果正在调用sed脚本文件

基本sed命令

p 打印匹配行

= 显示文本行号

a\ 在定位行号后附加新文本信息

i\在定位行号前插入新文本信息

d 删除定位行

c\用新文本替换定位文本

s 使用替换模式替换相应模式

r 从另一个文件中读文本

w 写文本到一个文件

shell

q 第一个模式匹配完成后退去

l 显示与八进制ascii代码等价的控制字符

{}在定位行执行命令组

n 从一个文件中读文本下一行,并附加在下一行

g 将模式2粘贴到/pattern n/

y 传送字符

eg.

[test@szbirdora 1]$ sed -n '2p' myfile

c

打印myfile第2行

[test@szbirdora 1]$ sed -n '2,4p' myfile

c

f

b

打印第二行到第四行

[test@szbirdora 1]$ sed -n '/a/p' myfile

a

打印匹配a的行

[test@szbirdora 1]$ sed -n '2,/2/p' myfile

c

f

b

1

2

打印第二行到匹配'2'的行

s命令替换

[test@szbirdora 1]$ sed 's/b/a/p' myfile

a

a

a

c

d

e

替换b为a

多点编辑 -e

eg. (myfile包含a-e)

[test@szbirdora 1]$ sed -e '2d' -e 's/c/d/' myfile 11

a

d

d

e

shell

sed命令r ---从文件中读取选定的行,读入输入文件中,显示在匹配的行后面

eg.

[test@szbirdora 1]$ cat 11

*******************Alaska***************

[test@szbirdora 1]$ sed '/a/r 11' myfile

a

*******************Alaska***************

b

c

d

e

写入命令:w 将输入文件中的匹配行写入到指定文件中

eg.

[test@szbirdora 1]$ cat 11

b

[test@szbirdora 1]$ sed -n '/a/w 11' myfile

[test@szbirdora 1]$ cat 11

a

追加:a 将文本追加到匹配行的后面。sed要求在a后加\,不止一行的以\连接

eg.

[test@szbirdora 1]$ sed '/b/a\****************hello*************\-------------china---------' myfile a

b

****************hello*************-------------china---------

c

d

e

插入命令:i 将文本插入到匹配行的前面。sed要求在a后加\,不止一行的以\连接 eg.

[test@szbirdora 1]$ sed '/b/i\

> THE CHARACTER B IS BEST\

> *******************************' myfile

a

THE CHARACTER B IS BEST

*******************************

b

c

d

e

shell

下一个:n 从一个文件中读文本下一行,并附加在下一行

退出命令 q 打印多少行后退出

eg.

[test@szbirdora 1]$ sed '3q' myfile

a alert

b best

c cook

sed script:

sed -f scriptfile myfile

5.awk介绍

awk可从文件或字符串值基于指定规则浏览和抽取信息

awk三种调用方式:

1.命令行方式

awk [-F field-sperator]'pattern{active}' input-files

awk [-F field-sperator]'command' input-files

awk脚本

所有awk命令插入一个文件,并使awk程序可执行,然后用awk命令解析器作为脚本的首行,以便通过键入脚本名称来调用。

awk命令插入一个单独文件

awk -f awk-script-file input-files

awk脚本由模式和动作组成

分隔符、域、记录

注意这里的$1,$2是域与位置变量$1,$2不一样。$0文件中的所有记录

eg:

awk '{print $0}' myfile

awk 'BEGIN {print "IP DATE ----"}{print $1"\t"$4}END{print "end-of -report"}

[test@szbirdora 1]$ df |awk '$1!~"dev"'|grep -v Filesystem

none 1992400 0 1992400 0% /dev/shm

[test@szbirdora 1]$ df |awk '{if ($1=="/dev/sda1") print $0}'

/dev/sda1 20641788 3367972 16225176 18% /

[test@szbirdora shelltest]$ cat employee

Tom Jones 4424 5/12/66 543354

Mary Adams 5346 11/4/63 28765

Sally Chang 1654 7/22/54 650000

Billy Black 1683 9/23/44 336500

[test@szbirdora shelltest]$ awk '/[Aa]dams/' employee

Mary Adams 5346 11/4/63 28765

[test@szbirdora shelltest]$ sed -n '/[Aa]dams/p' employee

Mary Adams 5346 11/4/63 28765

shell

[test@szbirdora shelltest]$ grep '[Aa]dams' employee

Mary Adams 5346 11/4/63 28765

三种命令方式下,使用模式匹配查询

[test@szbirdora shelltest]$ awk '{print $1}' employee

Tom

Mary

Sally

Billy

打印文件第一列

[test@szbirdora shelltest]$ awk '/Sally/{print $1"\t"$2}' employee

Sally Chang

打印匹配Sally的行的第一列和第二列

[test@szbirdora shelltest]$ df |awk '$4>20884623'

Filesystem 1K-blocks Used Available Use% Mounted on

/dev/sda2 82567220 17488436 60884616 23% /u01

/dev/sda4 28494620 4589172 22457992 17% /u02

打印df输出第四列大于××的行

格式输出:

打印函数—

[test@szbirdora shelltest]$ date

Mon Mar 10 15:15:47 CST 2008

[test@szbirdora shelltest]$ date |awk '{print "Month:" $2"\nYear:" $6}'

Month:Mar

Year:2008

[test@szbirdora shelltest]$ awk '/Sally/{print "\t\tHave a nice day,"$1"\t"$2}' employee Have a nice day,Sally Chang

printf函数

[test@szbirdora shelltest]$ echo "LINUX"|awk '{printf "|%-10s|\n",$1}'

|LINUX |

[test@szbirdora shelltest]$ echo "LINUX"|awk '{printf "|%10s|\n",$1}'

| LINUX|

~匹配符

[test@szbirdora shelltest]$ awk '$1~/Tom/{print $1,$2}' employee

Tom Jones

awk 给表达式赋值

关系运算符:

< 小于

shell

> 大于

== 等于

!= 不等于

>= 大于等于

<= 小于等于

~ 匹配

!~ 不匹配

eg.

[test@szbirdora shelltest]$ cat employee

Tom Jones 4424 5/12/66 543354

Mary Adams 5346 11/4/63 28765

Sally Chang 1654 7/22/54 650000

Billy Black 1683 9/23/44 336500

[test@szbirdora shelltest]$ awk '$2~/Adams/' employee

Mary Adams 5346 11/4/63 28765

条件表达式:

condition expression1?expression2:expression3

eg.

awk '{max=($1>$2) ? $1:$2;print max}' filename

运算符

+,-,*,/,%,^,&&,||,!

[test@szbirdora shelltest]$ cat /etc/passwd |awk -F: '\

NF!=7{\

printf("line %d does not have 7 fields:%s\n",NR,$0)}\

$1!~/[A-Za-z0-9]/{printf("line %d,nonalphanumberic user id:%s\n",NR,$0)}\

$2=="*"{printf("line %d,no password:%s\n",NR,$0)}'

awk编程

递增操作符 x++,++x

递减操作符 x--,--x

BEGIN模块

BEGIN模块后面紧跟着动作块,在读入文件前执行。通常被用来改变内建变量的值,如:FS\RS\OFS,初始化变量的值和打印输出标题。

[test@szbirdora shelltest]$ awk 'BEGIN{print "HELLO WORLD"}'

HELLO WORLD

[test@szbirdora shelltest]$ awk 'BEGIN{print "---------LIST---------"}{print}END{print "------END--------"}' donors

---------LIST---------

Mike Harrington:(510) 548-1278:250:100:175

Christian Dobbins:(408) 538-2358:155:90:201

shell

Susan Dalsass:(206) 654-6279:250:60:50

Archie McNichol:(206) 548-1348:250:100:175

Jody Savage:(206) 548-1278:15:188:150

Guy Quigley:(916) 343-6410:250:100:175

Dan Savage:(406) 298-7744:450:300:275

Nancy McNeil:(206) 548-1278:250:80:75

John Goldenrod:(916) 348-4278:250:100:175

Chet Main:(510) 548-5258:50:95:135

Tom Savage:(408) 926-3456:250:168:200

Elizabeth Stachelin:(916) 440-1763:175:75:300

------END--------

重定向和管道

输出重定向

awk输出重定向到一个文件需要使用输出重定向符,输出文件名需要用双引号括起来。

[test@szbirdora shelltest]$ awk -F: '{print $1,$2>"note"}' donors

[test@szbirdora shelltest]$ cat note

Mike Harrington (510) 548-1278

Christian Dobbins (408) 538-2358

Susan Dalsass (206) 654-6279

Archie McNichol (206) 548-1348

Jody Savage (206) 548-1278

Guy Quigley (916) 343-6410

Dan Savage (406) 298-7744

Nancy McNeil (206) 548-1278

John Goldenrod (916) 348-4278

Chet Main (510) 548-5258

Tom Savage (408) 926-3456

Elizabeth Stachelin (916) 440-1763

输入重定向

getline函数

[test@szbirdora shelltest]$ awk 'BEGIN{"date +%Y"|getline d;print d}'

2008

[test@szbirdora shelltest]$ awk -F"[ :]" 'BEGIN{printf "What is your name?";\

getline name<"/dev/tty"}\

$1~ name{print "Found\t" name "\ton line",NR"."}\

END{print "see ya," name "."}' donors

What is your name?Jody

Found Jody on line 5.

see ya,Jody.

[test@szbirdora shelltest]$ awk 'BEGIN{while(getline<"/etc/passwd">0)lc++;print lc}'

shell

从文件中输入,如果得到一个记录,getline函数就返回1,如果文件已经到了末尾,则返回0,如果文件名错误则返回-1.

管道:

awk命令打开一个管道后要打开下一个管道需要关闭前一个管道,管道符右边可以使用“”关闭管道。在同一时间只有一个管道存在

[test@szbirdora shelltest]$ awk '{print $1,$2|"sort -r +1 -2 +0 -1"}' names

tony tram

john smith

dan savage

john oldenrod

barbara nguyen

elizabeth lone

susan goldberg

george goldberg

eliza goldberg

alice cheba

|后用""关闭管道

system函数

system("LINUX command")

system("cat" $1)

system("clear")

条件语句

1.if(){}

2.if(){}

else{}

3.if(){}

else if(){}

else if(){}

else{}

[test@szbirdora shelltest]$ awk -F: '{if ($3>250){printf "%-2s%13s\n",$1,"-----------good partman"}else{print $1}}' donors

循环语句

[test@szbirdora shelltest]$ awk -F: '{i=1;while(i<=NF){print NF,$i;i++}}' donors 循环控制语句break、continue

程序控制语句

next从输入文件中读取下一行,然后从头开始执行awk脚本

{if($1~/Peter/){next}

else{print}}

shell

exit 结束awk语句,但不会结束END模块的处理。

数组:

awk '{name[x++]=$1;for(i=0;i<NR;i++){print i,name[i]}}' donors

(P177)---2008.3.11

awk内建函数

sub(正则表达式,替换字符[,$n]) ---域n匹配正则表达式的字符串将被替换。

[test@szbirdora shelltest]$ awk '{sub(/Tom/,"Jack",$1);print}' employee

Jack Jones 4424 5/12/66 543354

Mary Adams 5346 11/4/63 28765

Sally Chang 1654 7/22/54 650000

Billy Black 1683 9/23/44 336500

Jack He 3000 8/22/44 320000

index函数 index(字符串,子字符串) 子字符串在字符串中的位置

[test@szbirdora shelltest]$ awk 'BEGIN{a=index("hello","llo");print a}'

3

length函数 length(string) 字符串的长度

[test@szbirdora shelltest]$ awk 'BEGIN{a=length("hello world");print a}'

11

substr函数 substr(字符串,开始位置[,子字符串长度])

[test@szbirdora shelltest]$ awk 'BEGIN{a=substr("hello world",7);print a}'

world

[test@szbirdora shelltest]$ awk 'BEGIN{a=substr("hello world",7,3);print a}'

wor

match(string,正则表达式) 找出字符串中第一个匹配正则表达式的位置,其内建变量RSTART为匹配开始位置,RLENGTH为匹配开始后字符数

[test@szbirdora shelltest]$ awk '{a=match($0,/Jon/);if (a!=0){print NR,a}}' employee 1 5

[test@szbirdora shelltest]$ awk '{a=match($0,/Jon/);if (a!=0){print

NR,a,RSTART,RLENGTH}}' employee

1 5 5 3

toupper和tolower函数

[test@szbirdora shelltest]$ awk 'BEGIN{a=toupper("hello");print a}'

HELLO

split函数 split(string,array,fieldseperator)

shell

[test@szbirdora shelltest]$ awk 'BEGIN{"date"|getline d;split(d,date);print date[2]}' Mar

时间函数

systime() ----1970年1月1日到当前忽略闰年得出的秒数。

strftime(格式描述,时间戳)

[test@szbirdora shelltest]$ awk 'BEGIN{d=strftime("%T",systime());print d}'

13:08:09

[test@szbirdora shelltest]$ awk 'BEGIN{d=strftime("%D",systime());print d}'

03/12/08

[test@szbirdora shelltest]$ awk 'BEGIN{d=strftime("%Y",systime());print d}'

2008

6.sort介绍

sort:

-c 测试文件是否已经排序

-m 合并两个排序文件

-u 删除所有复制行

-o 存储sort结果的输出文件名

-t 域分隔符;用非空格或tab键分割域

+n n为域号,使用此域号开始排序 (注意0是第一列)

-r 逆序排序

n 指定排序是域上的数字排序项

[test@szbirdora 1]$ df -lh|grep -v 'Filesystem'|sort +1

none 2.0G 0 2.0G 0% /dev/shm

/dev/sda1 20G 3.3G 16G 18% /

/dev/sda4 28G 3.9G 22G 15% /u02

/dev/sda2 79G 17G 59G 23% /u01

uniq [option]files 从一个文本文件中去除或禁止重复行

-u 只显示不重复行

-d 只显示有重复数据行,每重复行只显示其中一行

-c 打印每一重复行出现次数

-f n为数字,前n个域被忽略

注意要先排序

7.split cut join 分割和合并文件命令

[test@szbirdora 1]$ split -l 2 myfile split (每两行分割为一个以split名称开头的文件)

[test@szbirdora 1]$ ls

case.sh df.out helloworld.sh iftest.sh myfile nohup.out nullfile.txt parm.sh splitaa splitab splitac splitad splitae

[test@szbirdora 1]$ cat splitaa

shell

Filesystem Size Used Avail Use% Mounted on /dev/sda1 20G 3.3G 16G 18% /

本文来源:https://www.bwwdw.com/article/stqm.html

Top