sed & gawk

#################################################################################
#                                 sed命令学习                                   #
#################################################################################

1.sed编辑器被称作流编辑器,跟普通交互文本编辑恰好相反。

2.sed编辑器可以基于输入到命令或是存储在命令文本文件中的命令来处理数据流中的数据。

它每次从输入中读取一行,用提供的编辑器命令匹配数据,按命令中指定的方式修改流中

数据,然后将生成的数据输出到STDOUT。


3.使用sed命令格式:

sed options sccipt file

选项            描述

-e script       在处理输入时,指script中指定的命令添加到运行命令中

-f file         在处理输入时,将file中指定的命令添加到运行的命令中

-n              不要为每个命令生成输出,等待print命令输出


1.1在命令行定义编辑命令

echo "This is a test"|sed 's/test/Laomeng/'   #//替换命令 's/test/text/'
This is a  Laomeng


vi data1


The quick brown jumps over the lazy log.
The quick brown jumps over the lazy log.
The quick brown jumps over the lazy log.
The quick brown jumps over the lazy log.


sed 's/log/cat/' data1  #//将log替换成cat
The quick brown jumps over the lazy cat.
The quick brown jumps over the lazy cat.
The quick brown jumps over the lazy cat.
The quick brown jumps over the lazy cat.

sed -e 's/brown/green/; s/log/cat/' data1  #//多处替换,将log替换成cat,将brown替换green


The quick green jumps over the lazy cat.
The quick green jumps over the lazy cat.
The quick green jumps over the lazy cat.
The quick green jumps over the lazy cat.


备注:必须记住,要在封尾单引号所在行结束命令。bash shell一旦发现在了封尾的单引号,就会

      执行命令。



1.2从文件中读取编辑命令

cat data1


The quick brown jumps over the lazy log.
The quick brown jumps over the lazy log.
The quick brown jumps over the lazy log.
The quick brown jumps over the lazy log.


vi script1
s/brown/green/
s/log/cat/

sed -f script1 data1    #//-f指定文件

The quick green jumps over the lazy cat.
The quick green jumps over the lazy cat.
The quick green jumps over the lazy cat.
The quick green jumps over the lazy cat.



#################################################################################
#                                gawk命令学习                                   #
#################################################################################


gawk功能:

   -.定义变量来保存数据

   -.使用算术和字符串操作来处理数据

   -.使用结构化编程概念,比如if-then语句和循环,来为处理数据加强逻辑

   -.提取数据文件的数据元素并将它们按照一定的顺序或格式来重新放置,从而生成格式化报告。

1.gawk命令格式:

   gawk options program file

   gawk选项:

   -F fs     指定行中分隔数据字段的字段分隔符

   -f file   指定读取程序的文件名

   -v var=value 定义gawk程序中的一个变量及其默认值

   mf N       指定要处理的数据文件中的最大字段数

   -W keyword 指定gawk的兼容模式或警告等级

1.1 从命令中读取程序脚本

  gawk '{print "Hello john"}'

hello
Hello john
hello
Hello john
this is test
Hello john

1.2使用数据字段变量

  -.$0代表整个文本行

  -.$1代表文件行中的第一个数据字段

  -.$2代表文件行中的第二个数据字段

  -.$n代表文本行中的第n个数据字段


cat data3

One line of test text.
Two line of test text.
Three line of test text.

gawk '{print $1}' data3   #//打印每行文本的第一列

One
Two
Three


gawk -F: '{print $1}' /etc/passwd   #//-F指定分隔":"为判断,取每行文本的第一个字段

root
bin
daemon
adm
lp
sync
shutdown
halt
.....


1.3在程序脚本中使用多个命令


echo " MY name is test " |gawk '{$4="Laomeng" ; print $0}' #//将文本行的第四个字体test替换成 laomeng,并打印整个文本行
" MY name is  Laomeng "


1.4从文件中读取程序

vi script2

{print $1 "'s home is directory is " $6}


gawk -F: -f script2 /etc/passwd   #//script2脚本程序会再次使用print命令打印/etc/passwd文件的主目录数据字段(字段变量$6),以及uesrid数据字段(字段变量$1)


root's home is directory is /root
bin's home is directory is /bin
daemon's home is directory is /sbin
adm's home is directory is /var/adm
lp's home is directory is /var/spool/lpd
sync's home is directory is /sbin
shutdown's home is directory is /sbin
halt's home is directory is /sbin
mail's home is directory is /var/spool/mail
uucp's home is directory is /var/spool/uucp
......



vi script3  #//script3定义了一变量来保存print命令中用到文本字符串。

{
  text = "'s home directory is "
  print $1 text $6
}

gawk -F: -f script3 /etc/passwd

root's home directory is /root
bin's home directory is /bin
daemon's home directory is /sbin
adm's home directory is /var/adm
lp's home directory is /var/spool/lpd
sync's home directory is /sbin
shutdown's home directory is /sbin
halt's home directory is /sbin
mail's home directory is /var/spool/mail
.........

1.5在处理数据前运行脚本 

gawk还允许指定程序脚本何时运行。默认情况下,gawk会从输入中读取一行文本,然后针对文本行的数据执行程序脚本。

gawk 'BEGIN{print "Hello world!!"}'
Hello world!!

cat laomeng4

Line 1
Line 2
Line 3

gawk 'BEGIN{print "The Laomeng4 File Contents:"} {print $0}' laomeng4  #//gawk执行BEGIN脚本后,它会用第二段脚本来处理文件数据
The Laomeng4 File Contents:
Line 1
Line 2
Line 3


1.6在处理数据后运行脚本

  跟BEGIN关键字类似,END关键字允许你指定一个程序脚本,gawk会读完数据后执行它:

gawk 'BEGIN{print "The Laomeng4 File Contents:"} {print $0} END{print "End of file"}' laomeng4
The Laomeng4 File Contents:
Line 1
Line 2
Line 3
End of file


vi script4

BEGIN {
print "The lalast list of usrs and shells"
print " UserID            Shell"
print "-------           -------"
FS=":"
}

{
print $1"                "$7
}

END {
print "The concludes the listing"
}


gawk -f script4 /etc/passwd
The lalast list of usrs and shells
 UserID            Shell
-------           -------
root               /bin/bash
bin                /sbin/nologin
daemon             /sbin/nologin
adm                /sbin/nologin
lp                 /sbin/nologin
sync               /bin/sync
shutdown           /sbin/shutdown
halt               /sbin/halt
........
The concludes the listing



#################################################################################
#                                sed编辑器基础                                  #
#################################################################################


1.替换标记

 vi laomeng5

This is a test of the test script.
This is the second test of the test script.

sed 's/test/laomeng/' laomeng5  #//substitute命令在替换多行中的文本时能正常工作,但默认情况下它能替换第行出现的第一处。
                                #//要让替换命令对一行中不同地方出现的文本都起作用,必须使用替换标记(substitution flas).

This is a laomeng of the test script.
This is the second laomeng of the test script.


多处替换
s/pattern/replement/flags

有四种可用的替换标记:

 -1.数字, 表明新文本将替换第几处模式匹配的地方;

 -2.g,  表明新文本将会替换所有已有文本出现地方;

 -3.p,  表明原来行的内容要打印出来;

 -4.w file, 将替换的结果写到文件中;

sed 's/test/laomeng/2' laomeng5  #//将每行第二处的test替换成laomeng
This is a test of the laomeng script.
This is the second test of the laomeng script.

sed 's/test/laomeng/g' laomeng5   #//g将文本行每处的test替换成 laomeng
This is a laomeng of the laomeng script.
This is the second laomeng of the laomeng script.


p替换标记会打印包含与substitute命令中指定的模式匹配的行。通常会和sed的 -n一起使用

vi laomeng6

This is a test line.
This is a different line.

sed -n 's/test/laomeng/p' laomeng6 #//-n选项将禁止sed编辑器输出。但p替换标记会输出修改过的行。将二才配合使用则会只输出被substitute命令修改过的行。
This is a laomeng line.


w替换标记产生同样的输出,不过将输出保存指定到文件中:

sed 's/test/laomeng/w 123.txt' laomeng6  #//将替换结果写到123.txt文件中
This is a laomeng line.
This is a different line.


2.替换字符

sed 's!/bin/bash!/bin/csh!' /etc/passwd   #//感叹号被用作字符串分隔符,使得路径很容易被读取和理解
root:x:0:0:root:/root:/bin/csh
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
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt


3.使用地址

  默认情况下,在sed编辑中使用命令会作用文本数据的所有行。如果你只想将命令作用于特定某行或某些行,

  必须使用行寻址(line addressing)

在sed编辑中有两种形式的行寻址:

-1.行的数字范围

-2.用文本模式过滤出某行

格式:

[address]command

address {
    command1
    command2
    command3
}

3.1数字方式的寻址

当使用数字方式的行寻址时,你可以用它们所在文本流中的行位置来引用行,

sed编辑器会将文本流中的第一行分配为第一行,然后继续按顺序为新行分配行号。

在命令中指定的地址可以是单个行号,或是用起始行号,逗号及结尾行号指定的一定范围内的行。

 vi laomeng1

The quick brown fox jumps over the lazy dog
The quick brown fox jumps over the lazy dog
The quick brown fox jumps over the lazy dog
The quick brown fox jumps over the lazy dog

sed '2s/dog/cat/' laomeng1  #//将第2行的dog替换cat
The quick brown fox jumps over the lazy dog
The quick brown fox jumps over the lazy cat
The quick brown fox jumps over the lazy dog
The quick brown fox jumps over the lazy dog

sed '2,3s/dog/cat/' laomeng1  #//将第二到三行的dog替换成cat
The quick brown fox jumps over the lazy dog
The quick brown fox jumps over the lazy cat
The quick brown fox jumps over the lazy cat
The quick brown fox jumps over the lazy dog


备注:可能你不知道文本中到底有多少行数据,所以美元符用起来很方便($)


3.2使用文件模式的过滤器

格式:

  /pattern/command

grep laomeng /etc/passwd
laomeng:x:505:505::/home/laomeng:/bin/bash

sed '/laomeng/s/bash/csh/' /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
.....
laomeng:x:505:505::/home/laomeng:/bin/csh


3.3组合命令

sed '2{
s/fox/elexplhant/
s/dog/cat/
}' laomeng1
The quick brown fox jumps over the lazy dog
The quick brown elexplhant jumps over the lazy cat
The quick brown fox jumps over the lazy dog
The quick brown fox jumps over the lazy dog

sed '3,${
s/brown/green/
s/lazy/active/
}' laomeng1
The quick brown fox jumps over the lazy dog
The quick brown fox jumps over the lazy dog
The quick green fox jumps over the active dog
The quick green fox jumps over the active dog


4.删除行

可以用delete

删除命令d名副其实,它会删除匹配指定寻址模式的所有行。使用删除命令时要特别小心,

因为你忘记了加一个寻址模式的话,流中的所有文本行都会被删除:


cat laomeng1

The quick brown fox jumps over the lazy dog
The quick brown fox jumps over the lazy dog
The quick brown fox jumps over the lazy dog
The quick brown fox jumps over the lazy dog

sed 'd' laomeng1

vi laomeng7

This is line number1.
This is line number2.
This is line number3.
This is line number4.



sed '3d' laomeng7 #//删除文本行中的第3行数据
This is line number1.
This is line number2.
This is line number4.


sed '2,3d' laomeng7  #//删除文本行中的第2到3行的数据
This is line number1.
This is line number4.


sed '3,$d' laomeng7  #//删除文本行中的第3行至尾部的数据
This is line number1.
This is line number2.


sed '/number1/d' laomeng7  #//文本匹配模式删除相关行的数据
This is line number2.
This is line number3.
This is line number4.


你可以删除用两个文本模式来删除某个范围内的行,操作要小心。指定第一个模式会 "打开" 行删除功能,

第二个模式会 "关闭" 行删除功能。

sed '/1/,/3/d' laomeng7  #//删除文本中的第1行到第3行数据

This is line number4.


vi laomeng8

This is line number 1.
This is line number 2.
This is line number 3.
This is line number 4.
This is line number 1 agin.
This is text you want to keep.
This is the last line in the file.

sed '/1/,/3/d' laomeng8

This is line number 4.

第二个出现数字"1"的行再次触发了删除命令,删除了数据流中的剩余行,因为停止模式再没找到。

当然,如果你指定一个从未在文本中出现的停止模式,会现在另一个问题:

sed '/1/,/5/d' laomeng8

因为删除功能在匹配到第一个模式的时候打开了,但一直没有匹配到结束模式,所以整个数据流都被删除了。


5.插入和附加文件

sed编辑器允许你向数据流插入和附加文本行。        -----------------(标记)

  -1.插入(insert)命令i会在指定行前增加一个新行;

  -2.追加(append)命令a会在指定行后增加一个新行;

sed '[address]command\
new line'

echo "Test line 2"|sed 'i\Test line 1'
Test line 1
Test line 2

echo "Test line 2"|sed 'a\Test line 1'
Test line 2
Test line 1


要给数据流中插入或附加数据,你必须用寻址来告诉sed编辑器你想数据出现在什么位置。

可以用这些命令时只能指定一个行地址。可以匹配一个数字行号或文本行号,但不能地址区间。

cat laomeng7

This is line number1.
This is line number2.
This is line number3.
This is line number4.

sed '3i\This is an insered line.' laomeng7  #//在文本行中第三行之前插入一行新的数据。
This is line number1.
This is line number2.
This is an insered line.
This is line number3.
This is line number4.

sed '3a\This is an appened line.' laomeng7 #//在文本中第3行后附加一行新的数据
This is line number1.
This is line number2.
This is line number3.
This is an appened line.
This is line number4.

sed '$a\This is a new line of text.' laomeng7  #//在文本行中末尾附加一行新的数据
This is line number1.
This is line number2.
This is line number3.
This is line number4.
This is a new line of text.


6.修改行

修改(change)命令允许修改数据流中整行文本内容,它跟插入和附加命令的工作机制一样,你必须

在sed命令中单独指定新行:

cat laomeng7

This is line number1.
This is line number2.
This is line number3.
This is line number4.

sed '3c\This is a changed line of test.' laomeng7  #//修改文本行中第3行的内容
This is line number1.
This is line number2.
This is a changed line of test.
This is line number4.

sed '/number3/c\This is a changed line of test.' laomeng7  #//文本模式匹修改文本行的某一行的内容
This is line number1.
This is line number2.
This is a changed line of test.
This is line number4.


sed '2,3c\This is a new line of text.' laomeng7 #//将文本行中第2到3行中内容替换成....
This is line number1.
This is a new line of text.
This is line number4.



7.转换命令

转换(transfrom, y)命令是唯一可以处理单个字符的sed编辑器命令,命令格式如下:

[address]y/inchars/outchars/

转换命令进行inchar和outchar值的一对一映射。

inchar中的第一字符会被转换为outchar中的第一个字符,第二个字符也被转换成outchars中的第二字符。

这个映射会一直持续处理完成指定字符。如果inchar和outchar的长度不同,则sed编辑器会产生一个错误消息。


cat laomeng8

This is line number 1.
This is line number 2.
This is line number 3.
This is line number 4.
This is line number 1 agin.
This is text you want to keep.
This is the last line in the file.

sed 'y/123/789/' laomeng8
This is line number 7.
This is line number 8.
This is line number 9.
This is line number 4.
This is line number 7 agin.
This is text you want to keep.
This is the last line in the file.


echo "This 1 is a test of 1 try." |sed 'y/123/789/'
This 7 is a test of 7 try.

sed编辑器替换在文本行中匹配到字符"1"的两个实例,你无法限定只更改字符出现的特定某个地方。


8.回顾打印

   -1.小字p命令用来打印文本行;

   -2.等号(=)命令来打印行号;

   -3.l(L的小写)命令用来列出行。

 8.1打印行


echo "This is a test"|sed 'p'
This is a test
This is a test


cat laomeng7
This is line number1.
This is line number2.
This is line number3.
This is line number4.

sed -n '/number3/p' laomeng7  #//-n选项,禁止其他行,只打印包含匹配的文本模式
This is line number3.



sed -n '2,3p' laomeng7
This is line number2.
This is line number3.

sed -n '/3/{p; s/line/laomeng/p}' laomeng7 #//sed编辑器命令会查找包含数字“3”的行,然后执行两条命令。
                                           #//首先,脚本用p命令来打印出该原来的;然后它用s命令替换原版本。
                       #//输出同时显示了原来的文本和新的文本。

This is line number3.
This is laomeng number3.


8.2打印行号

  等号命令会打印行在数据流中的当前行号。行号由数据流中的换行符决定。

  每次出现一个先行符,sed编辑器会认为它结束了一行文本。


sed '=' laomeng1
1
The quick brown fox jumps over the lazy dog
2
The quick brown fox jumps over the lazy dog
3
The quick brown fox jumps over the lazy dog
4
The quick brown fox jumps over the lazy dog

sed '=' laomeng7
1
This is line number1.
2
This is line number2.
3
This is line number3.
4
This is line number4.

sed -n '/number4/{p; =}' laomeng7
This is line number4.
4

8.3列出行

 列出命令(l)允许打印数据流中的文本和不可打印的ACSII字符。任何不可打印字符都用它们的八进制值前加

 一个反斜线或标准C风格的命名法,比如\t来代表制表符;

cat laomeng9 

This  line  contains   tabs.

sed -n 'l' laomeng9
This  line  contains   tabs.$


9.用sed和文件一起工作

  替换命令包含允许你和文件一起工作的标记。

9.1向文件写入,格式:

  [address]w file   #//file可以指定文件的相对路径或绝对路径


sed '1,2w jack.txt' laomeng7  #//将文本行中的1,2行数据写入到jack.txt文件中去
This is line number1.
This is line number2.
This is line number3.
This is line number4.


cat laomeng11

Blum, Kate  Chicago, IL
Mullen, Riley West Lafayette, IN
Snell, Haley Ft.Wayne, IN
Woneker, Matthew    Springfield, IL
Wiseccarrver, Emma  Grant Park, IL


sed -n '/IN/w INcustomers' laomeng11

cat INcustomers 
Mullen, Riley West Lafayette, IN
Snell, Haley Ft.Wayne, IN

9.2从文件读取数据

  读取命令(r)允许你将一个独立文件中的数据插入到数据流中。

  读取命令的格式如下:

  [address]r filename

  filename参数指定数据文件的绝对或相对路径名。

vi laomeng12

This is an added line.
This is the second added line.

sed '3r laomeng12' laomeng7 #//读取laomeng12文件附加到文件laomeng7的第3行后面
This is line number1.
This is line number2.
This is line number3.
This is an added line.
This is the second added line.
This is line number4.




sed '/number2/r laomeng12' laomeng7
This is line number1.
This is line number2.
This is an added line.
This is the second added line.
This is line number3.
This is line number4.



sed '$r laomeng12' laomeng7
This is line number1.
This is line number2.
This is line number3.
This is line number4.
This is an added line.
This is the second added line.

vi latter

Would the following people:
LIST
please report to the office.

cat laomeng11

Blum, Kate  Chicago, IL
Mullen, Riley West Lafayette, IN
Snell, Haley Ft.Wayne, IN
Woneker, Matthew    Springfield, IL
Wiseccarrver, Emma  Grant Park, IL

sed '/LIST/{
r laomeng11
d
}' latter
Would the following people:
Blum, Kate  Chicago, IL
Mullen, Riley West Lafayette, IN
Snell, Haley Ft.Wayne, IN
Woneker, Matthew    Springfield, IL
Wiseccarrver, Emma  Grant Park, IL
please report to the office.




#################################################################################
#                                正则表达式                                     #
#################################################################################


正则表达式是你定义的,linux工具用来过滤文本的模式模板。



数据流----------------->正则表达式--------------------->匹配的数据
                            |
                |
                |
                |
                |
                |
                |
                |
                |过滤掉的数据
                |
                |
                |
                |
                |
                |



正则表达式是用正则表达式引擎(regular expression engine)实现的。

正则表达式引擎是解释正表达式模式并使用这些模式进行文本匹配的底层软件。


在linux,有两种流行的正则表达式引擎:

 -1.POSIX基本正则表达式(BRE)引擎

 -2.POSIX扩展正则表达式(ERE)引擎


 sed使用 BRE引擎

 gawk使用ERE引擎



1.定义BRE模式

最基本的BRE模式是匹配数据流中的文本字符。

1.1纯文本

echo "This is a test"|sed -n '/test/p'
This is a test

echo "This is a test" |sed -n '/trial/p'

echo "This is a test" |gawk '{print $0}'
This is a test

echo "This is a test" |gawk '/test/{print $0}'
This is a test     

echo "This is a test"|gawk '/trial/{print $0}'

备注:第一条原则是下达表达式模式都区分大小写。


echo "This is a test" |sed -n '/this/p'

echo "This is a test"|sed -n '/This/p'
This is a test


echo "The books are expensive"|sed -n '/books/p'
The books are expensive

echo "The book are is expensive" |sed -n '/books/p'

echo "This is line number 1" |sed -n '/ber 1/p'
This is line number 1

echo "This is line number1" |sed -n '/ber 1/p'


1.2特殊字符

正则表达式识别的的特殊字符包括:

*[]^$\+?|()

vi laomeng2

The cost is $4.00

sed -n '/\$/p' laomeng2
The cost is $4.00

由于反斜线是特殊字符,如果你要在正达表达式模式中使用它,你必须转义,这样就产生了两个反斜线:

echo "\ is a special character" |sed -n '/\\/p'
\ is a special character

echo "3 / 2" |sed -n '///p'
sed: -e expression #1, char 3: unknown command: `/'

echo "3 / 2" |sed -n '/\//p'
3 / 2


2.锚字符

  当你指定一个正达表达式模式时,只要模式出现在数据流中的任务地方,它都会匹配。

  有两个特殊字符可以用来将模式锁在数据流中的行首或行尾

  2.1锁定在行首

     脱字符(caret character, ^)定义从数据流中文本行的行首开始的模式。如果模式位于其他位置而不是

     文本行的行首,正则表达式会不成立。

    echo "The book store" |sed -n '/^book/p'

    echo "Books are great" |sed -n '/^Book/p'
    Books are great

    备注:区分大小写字母

脱字符会在每个由换行符决定的新数据行的行首检查模式:

 vi laomeng3

This is a test line.
this is another test line.
A line tha tests this feature.
Yet more testing of this.



sed -n '/^this/p' laomeng3
this is another test line.


echo "This ^ is a test"|sed -n '/s ^/p'
This ^ is a test


echo "This ^ is a test"|sed -n '/\^/p'
This ^ is a test

如果指定正则表达式模式只用了脱字符,你不需要用反斜线来转义。

但如果你在模式先指定了脱字符,后跟一些额的文本,那么你必须在脱字符前用转义字符。


2.2锁定在行尾

    跟在行首查找模式相对的就是在行尾查找。美元($)特殊字符定义了行尾锚点。

    将这个特殊的字符加在文本模式之后来指明数据行必须以该文本模式结尾:

echo "This is a good book" |sed -n '/book$/p'
This is a good book

echo "The book is good" |sed -n '/book$/p'

echo "There are a lot of good books" |sed -n '/book$/p'

将尾部的单词book改成复数形式,就意味着它不在匹配下达表达式模式了,尽管book仍然在数据流中。

文本模式必须是模式匹配的行最后的部分。


2.3组合锚点

vi laomeng10

this is a test of using both anchors
I said this is a test
this is a test
I'm sure this is a test.

sed -n '/^this is a test$/p' laomeng10
this is a test


vi laomeng13

This is one test line.

This is another test line.

sed '/^$/d' laomeng13
This is one test line.
This is another test line.

定义的正则表达式模式会查找行首和行尾之间什么都没有的那些行。由于空白行在两个行符之间没有文本,

他们刚好匹配了下达表达式模式,sed编辑器用删除命令d来删除匹配该正则表达式模式的行,因此删除文件中

的所有空白行。


2.4点字符

点字符用来匹配任意的单字符,除了换行符。

但点字符必须匹配一个字符,如果点字符的位置没字符,那么模式就不成立。



vi laomeng14

This is a test of a line.
The cat is sleeping.
That is a very nice hat.
This test is at line four.
at ten o'clock we'll go home.

sed -n '/.at/p' laomeng14  
The cat is sleeping.
That is a very nice hat.
This test is at line four.

2.5字符组

点特殊字符在任意字符来匹配某个位置时很有用。但如果你限定匹配哪些字符呢?

在正则表达式中,这些称为字符组(character class)



vi laomeng14

This is a test of a line.
The cat is sleeping.
That is a very nice hat.
This test is at line four.
at ten o'clock we'll go home.


sed -n '/[ch]at/p' laomeng14  #//匹配文本行中有包含[ch]at的单词
The cat is sleeping.
That is a very nice hat.


echo "Yes"|sed -n '/[Yes]/p'
Yes

echo "yEs"|sed -n '/y[Ee]s/p'
yEs

echo "Yes"|sed -n '/[Yy]es/p'
Yes


echo "yeS"|sed -n '/ye[Ss]/p'
yeS

echo "Yes"|sed -n '/[Yy][Ee][Ss]/p'
Yes

echo "yEs"|sed -n '/[Yy][Ee][sS]/p'
yEs

echo "YeS"|sed -n '/[Yy][Ee][Ss]/p'
YeS


vi laomeng16

4353
60633
46201
223001
4353
22203

sed -n '/[0-9][0-9][0-9][0-9][0-9]/p' laomeng16    #//成功过滤了过短的数字,因为最后一个字符组没有字符可匹配,打印出六位数
60633
46201
223001
22203



sed -n '/^[0-9][0-9][0-9][0-9][0-9]$/p' laomeng16  #//加上行首和行尾来界定,成功过滤出5位数
60633
46201
22203



字符组的一个极其常见的用法就是解析拼错的单词,比如用户输入的数据。

可能用创建正则表达式来接受数据中常见的拼写错误。


vi laomeng17

I need to have some maintenance done on my car.
I'll pay that in a seperate invoice.
After I pay for the maintenance my car will be as good as new.


sed -n '/mainten[ae]nce/p ; /sep[ea]r[ea]te/p' laomeng17
I need to have some maintenance done on my car.
I'll pay that in a seperate invoice.
After I pay for the maintenance my car will be as good as new.


2.5排除字符组

   在正则表达式模式中,可以反转字符组。可以寻找组中没有的任意字符,而不是寻找组中含有的字符

   只要在字符组的开头加个脱字符:


vi data6

the cat is a hat.
This test at line two.

sed -n '/[^ch]at/p' data6  #//通过排除字符组,正则表达模式会匹配c或h之后的任何字符,以及文本模式。
                           #//由于空格字符也在这类字符中,它通过了模式、
This test at line two.


2.6使用区间

你可以用单破折线符号来在字符组中使用字符区间。

[0-9][a-z][A-Z][a-zA-Z][a-zA-Z0-9]


echo "a8239"|sed -n '/[a-z][0-9]/p'
a8239

echo "a8239"|sed -n '/[0-9][0-9][0-9][0-9][0-9]/p'

echo "a8239"|sed -n '/[a-z0-9][0-9][0-9][0-9][0-9]/p'
a8239

echo "8239a"|sed -n '/^[0-9][0-9][0-9][0-9][0-9]$/p'



cat laomeng14

This is a test of a line.
The cat is sleeping.
That is a very nice hat.
This test is at line four.



sed -n '/[a-ch-m]at/p'  laomeng14
The cat is sleeping.
That is a very nice hat.




cho "I'am getting too fat."|sed -n '/[^a-ch-m]at/p'
I'am getting too fat.

echo "I'am getting too fat."|sed -n '/[a-ch-m]at/p'


2.7特殊字符组

  BRE包含了可用来匹配特殊字符类型的特殊字符组。

  [[:alpha:]]    匹配任意字母字符,不管是大写还是小写

  [[:alnum:]]    匹配任意字母数字字符0-9,A-Z或a-z

  [[:blank:]]    匹配空格或制表符

  [[:digit:]]    匹配0~9之间的数字

  [[:lower:]]    匹配小写字母字符a-z

  [[:print:]]    匹配任意可打印字符

  [[:punct:]]    匹配标点符号

  [[:space:]]    匹配任意空白字符:空格,制表符,NL ,FF , VT 和 CR

  [[:upper:]]    匹配任意大写字母字符A-Z

echo "abc" |sed -n '/[[:digit:]]/p'

echo "abc"|sed -n '/[[:alpha:]]/p'
abc

echo "abc123"|sed -n '/[[:digit:]]/p'
abc123

echo "abc123"|sed -n '/[[:alnum:]]/p'
abc123

echo "This is, a test"|sed -n '/[[:punct:]]/p'
This is, a test

echo "This is a test"|sed -n '/[[:punct:]]/p'



2.8星号(*)

在字符后面放置星号(*)说明该字符将会在匹配模式的文本中出现0或多次:

这个模式广泛应用于处理常见拼写错误或在不同语言中有拼写变种的单词。

echo "ik" |sed -n '/ie*k/p'
ik

echo "iek"|sed -n '/ie*k/p'
iek

echo "ieek"|sed -n '/ie*k/p'
ieek

echo "ieeeek"|sed -n '/ie*k/p'
ieeeek

echo "ieeek"|sed -n '/ie*k/p'
ieeek

echo "I'm getting a color TV" |sed -n '/colou*r/p'  #//u*表明字母可能出现或不出现在匹配模式文本中。
I'm getting a color TV


echo "I'm getting a colour TV"|sed -n '/colou*r/p'
I'm getting a colour TV

echo "I ate a potatoe with my lunch."|sed -n '/potatoe*/p'
I ate a potatoe with my lunch.

echo "I ate a potato with my lunch."|sed -n '/potatoe*/p'
I ate a potato with my lunch.


另一个方面的特性是将点(.)特殊字符和星号(*)特殊字符结合起来。这个组合提供了匹配了任意多个

任意字符的模式。通常用在数据流中两个可能相邻或不相邻的文本字符串之间:


echo "this is a reular pattern expression"|sed -n '/reular.*expression/p'
this is a reular pattern expression


它允许指定可能在文本中出现多次的一组字符或一个字符区间:

echo "bt"|sed -n '/b[et]*t/p'
bt

echo "bat"|sed -n '/b[ae]*/p'
bat

echo "bet"|sed -n '/b[ae]*t/p'
bet

echo "btt"|sed -n '/b[ae]*t/p'
btt

echo "baat"|sed -n '/b[ae]*t/p'
baat

echo "baaeet"|sed -n '/b[ae]*t/p'
baaeet

echo "baeeaeeat"|sed -n '/b[ae]*t/p'
baeeaeeat

echo "beakeet"|sed -n '/b[ae]*t/p'

只要a and e出现在b and t字符中的任意组合中(包括根本不出现的情况),模式就匹配了。

如果有任何不在定义的字符组内的其他字符出现,该模式匹配就会不成立。



#################################################################################
#                              扩展正则表达式                                   #
#################################################################################



POSIX ERE模式包括供一些LINUX应用和工具使用的若干额外符号。

gawk程序能够识别ERE模式,但sed不能。


备注:记住sed编辑器和gawk程序的正则表达式引擎之间是有区别的。

gawk程序可以使用大多扩展正则表达式模式匹配符号,并且能提供一些额外的sed编辑器没的额外

过滤功能。但正因为如此,它通常在处理数据流时更慢。


1.1问号(?)

  问号类似于星号,不过有点细微的不同。问表明前面的字符可以出现0或1次,但只限于些。

  它不会匹配多次出现的该字符:


echo "bt" |gawk '/be?t/{print $0}'
bt

echo "bet"|gawk '/be?t/{print $0}'
bet

echo "beet"|gawk '/be?t/{print $0}'

echo "beeet"|gawk '/be?t/{print $0}'

如果e字符并未在文本中出现,或者它只在文本中出现了一次,那么模式会匹配。


跟星号一样,可以将?问号符和字符组一起使用:

echo "bt"|gawk '/b[ae]?t/{print $0}'
bt

echo "bat"|gawk '/b[ae]?t/{print $0}'
bat

echo "bot"|gawk '/b[ae]?t/{print $0}'


echo "bet"|gawk '/b[ae]?t/{print $0}'
bet

echo "baet"|gawk '/b[ae]?t/{print $0}'

echo "beat"|gawk '/b[ea]?t/{print $0}'

echo "beet"|gawk '/b[ae]?t/{print $0}'


如果字符组中的字符出现了0次或1,模式匹配就成立。如果两字符都出现了,或者如果其中一个字符

出现了两次,模式匹配都不成立。


2.加号(+)

  加号类似于星号另一个模式符号,但跟问号也有不同。加号表明前面的字符可以出现1次或多次,

  但必须至少出现1次。如果该字符没有出,那么模式就不会匹配:



echo "beet" |gawk '/be+t/{print $0}'
beet

echo "beeet"|gawk '/be+t/{print $0}'
beeet

echo "bet"|gawk '/be+t/{print $0}'
bet

echo "bt"|gawk '/be+t/{print $0}'



加号同样适用于字符组,跟星号和问号的使用方式相同:

echo "bt"|gawk '/b[ae]+t/{print $0}'


echo "bat"|gawk '/b[ae]+t/{print $0 }'
bat

echo "baet"|gawk '/b[ae]+t/{print $0 }'
baet


echo "bet"|gawk '/b[ae]+t/{print $0}'
bet

echo "beat"|gawk '/b[ae]+t/{print $0}'
beat

echo "beet"|gawk '/b[ae]+t/{print $0}'
beet

echo "beeat"|gawk '/b[ae]+t/{print $0}'
beeat



3.使用花括号

  ERE中的花括号允许你为可重复的正则表达式指定一个上限。这通常称为区间(interval).

  可以用个格式来指定区间:

  -1.m----正则表达式准确出现m次;

  -2.m, n----正则表达式至少出现m次,至多n次;


   备注:默认情况下,gawk程序不会识别正则表达式区间。你必须为gawk程序指定--re-interval命令

         选项来识别正则表达式区间。



echo "bt"|gawk --re-interval '/be{1}t/{print $0}'


echo "bet"|gawk --re-interval '/be{1}t/{print $0}'
bet

echo "beet"|gawk '/be{1}t/{print $0}'

通过指定区间为1,你限定了该字符在匹配模式的字符串出现的次数。

如果该字符出现了多次,模式匹配就不成立。

echo "beet"|gawk --re-interval  '/be{2}t/{print $0}'
beet


指定上限和下限:


echo "bt"|gawk --re-interval '/be{1,2}t/{print $0}'

echo "bet"|gawk --re-interval '/be{1,2}t/{print $0}'
bet

echo "beet"|gawk --re-interval '/be{1,2}t/{print $0}'
beet


echo "beeet"|gawk --re-interval '/be{1,2}t/{print $0}'

字符e可以出现一次或两次,这样模式匹配就能成立;否则,模式

匹配就不会成立。




区间匹配同样适用于字符组:

echo "bt" |gawk --re-interval '/b[ae]{1,2}t/{print $0}'

echo "bet"|gawk --re-interval '/b[ae]{1,2}t/{print $0}'
bet

echo "beat"|gawk --re-interval '/b[ae]{1,2}t/{print $0}'
beat

echo "beet"|gawk --re-interval '/b[ae]{1,2}t/{print $0}'
beet

echo "beeat"|gawk --re-interval '/b[ae]{1,2}t/{print $0}'

echo "baeet"|gawk --re-interval '/b[ae]{1,2}t/{print $0}'

echo "baeaet"|gawk --re-interval '/b[ae]{1,2}t/{print $0}'

如果在文件模式中有字母a或e的一到两个实例,这个正则表达式就会匹配。如果

在任何组合中有多于两个出现,它就不会匹配了。



4.管道符号

   管道符号允许你在检查数据时,用逻辑OR方式指定正则表达式引擎要用两个或多个模式。

   如果任何一个模式匹配了数据流文本,文本就通过了。如果没有模式匹配,数据流文本

   匹配就不成立。

   格式:expr|expr2|expr3


echo "The cat is asleep" |gawk '/cat|dog/{print $0}'
The cat is asleep

echo "The dog is asleept"|gawk '/cat|dog/{print $0}'
The dog is asleept

echo "The sheep is asleep"|gawk '/cat|dog/{print $0}'

这个例子会在数据流中查找正则表达式cat或dog。正则表达式和管道符号之间不能空格,

否则它们也会加到正则表达式模式中。

管道符号两侧的正则表达式都可用任何正则表达式模式(包括字符组)来定义模式:

echo "He has a hat."|gawk '/[ch]at|dog/{print $0}'
He has a hat.

5.聚合表达式(())

  正则表达式模式可以用圆括号聚合起来。当你聚合正则表达模式时,该组就会被成标准字符。

echo "Sat"|gawk '/Sat(urday)?/{print $0}'
Sat


cho "Saturday"|gawk '/Sat(urday)?/{print $0}'
Saturday


聚合和管道符号组:

echo "cat"|gawk '/(c|b)a(b|t)/{print $0}'
cat

echo "cab"|gawk '/(c|b)a|(b|t)/{print $0}'
cab

echo "bat"|gawk '/(c|b)a(b|t)/{print $0}'
bat

echo "bab"|gawk '/(c|b)a(b|t)/{print $0}'
bab

echo "tab"|gawk '/(c|b)a(b|t)/{print $0}'

echo "tac"|gawk '/(c|b)a(b|t)/{print $0}'

模式(c|b)a(b|t)会匹配第一组字母的任意组合以及第二组中字母的任意组合。




#################################################################################
#                             实用中的正则表达式                                #
#################################################################################


1.目录文件计数

echo $PATH |sed 's/:/ /g'
/usr/lib64/qt-3.3/bin /usr/local/sbin /usr/local/bin /sbin /bin /usr/sbin /usr/bin /root/bin

vi countfiles

#!/bin/bash
#count number of file in your PATH

mypath=`echo $PATH |sed 's/:/ /g'`
count=0
for laomeng in $mypath
do
  check=`ls $laomeng`
  for item in $check
  do
      count=$[ $count + 1 ]
  done
echo "$laomeng - $count"
count=0
done

sh countfiles 
/usr/lib64/qt-3.3/bin - 0
/usr/local/sbin - 1
/usr/local/bin - 0
/sbin - 284
/bin - 113
/usr/sbin - 339
/usr/bin - 1584
ls: cannot access /root/bin: No such file or directory
/root/bin - 0


2.验证电话号码

(123)456-7890
(123) 456-7890
123-456-7890
123.456.7890

'/^\(?[2-9][0-9]{2}\)(| |\.)?[0-9]{3}( |-|\.)[0-9]{4}$/'

#!/bin/bash
#script to filter out bad phone numbers
gawk --re-interval '/^\(?[2-9][0-9]{2}\)?(| |-|\.)[0-9]{3}( |-|\.)[0-9]{4}/{print $0}'

echo "317-555-1234"|gawk --re-interval '/^\(?[2-9][0-9]{2}\)?(| |-|\.)[0-9]{3}( |-|\.)[0-9]{4}/{print $0}'
317-555-1234

echo "000-555-1234"|./isphone 

vi phonelist

000-000-0000
123-456-7890
212-555-1234
(317)555-1234
(202) 555-9876
33520
123456789
234.123.4567


cat phonelist | ./isphone 
212-555-1234
(317)555-1234
(202) 555-9876
234.123.4567


3.解析邮件地址

usrename@hostname

username值可用字母字符以及以下特殊字符:

点号
单破折线
加号
下划线

gawk --re-interval '/^([a-zA-Z0-9_\-\.\+]+)@([a-zA-Z0-9_\-\.]+)([a-zA-Z]{2,5})$/{print $0}'




vi isEmail

#!/bin/bash
gawk --re-interval '/^([a-zA-Z0-9_\-\.\+]+)@([a-zA-Z0-9_\-\.]+)([a-zA-Z]{2,5})$/{print $0}'


echo "rich@here.now"| ./isEmail 
[email protected]


echo "rich@here.now."| ./isEmail 


echo "rich@here.n" |./isEmail


echo "rich@here-now"| ./isEmail 



echo "rich.hlum@here.now"|./isEmail 
[email protected]

echo "rich_blum@here.now"|./isEmail 
[email protected]

echo "rich/blum@here.now"|./isEmail

echo "rich#[email protected]"|./isEmail

echo "rich*[email protected]"|./isEmail




#################################################################################
#                               sed进阶                                         #
#################################################################################


sed编辑器包含了3个可用来处理多行文本的特殊命令:

N: 将数据流中的下一行加进来创建一个多行组来处理。

D:删除多行组中的一行。

P: 打印多行组中的一行。



1.单行的next命令

   小写的n命令会告诉sed编辑器移动到数据流中的下一文本行,而不用重新回到命令的最开始

   再重新执行一遍。记住,通常sed编辑器会在移动到数据流中的下一行文本前在这个行上执行

   所有定义好的命令。单行next命令改变了这个流程。


vi gm1

This is the header line.

This is data line.

This is the last line.



sed '/^$/d' gm1     #//删除全部空白行
This is the header line.
This is data line.
This is the last line.


sed '/header/{n;d}' gm1  #//删除匹配header行下的空白行
This is the header line.
This is data line.

This is the last line.


2.合并文本行

  单行next命令会将数据流中的下一文本行移动到sed编辑器的工作空间(称为模式空间)。

  多行版本的next命令(用大写N)会将一文本行加到已经在模式空间的文本上。

  这样的作用是将数据流中的两个文本行合并到同一个模式空间。


 vi gm2

This is the header line.
This is the first data line.
This is the second data line.
This is the last line.


sed '/first/{N ; s/\n/ / }' gm2
This is the header line.
This is the first data line. This is the second data line.
This is the last line.

sed编辑器会查找含有单词first的那行文本。当它找到了该行,它会用N命令将下行合并到那行,

然后用替换命令s将换行符替换成空格。结果是文本文件中的两行中的两行在sed编辑器的输出中成了一行


vi gm3

The first meeting of the Linux System
Administrator's group will be held on Tuesday.
All System Administrators should atted this meeting.
Thank you for your attendance.

sed  's/System Administrator/Destop User/' gm3
The first meeting of the Linux System
Administrator's group will be held on Tuesday.
All Destop Users should atted this meeting.
Thank you for your attendance.

替换命令会在文本中查找特定的双词短语System Administrator.短语在一行中的话,

事情很好处理,替换命令可以直接替换文本。但是如果短语被分成了两行,替换命令

就无法识别匹配的模式了。

sed 'N; s/System.Administrator/Desktop User/' gm3
The first meeting of the Linux Desktop User's group will be held on Tuesday.
All Desktop Users should atted this meeting.
Thank you for your attendance.


用N命令将下一行和发现第一个单词的那行合并后,即使短语内出现了换行,你仍然可以找到它


注意:替换命令在System和Administrator之间用了通配符模式(.)来匹配空格和换行这两种情况

但当它匹配了换行时,它就从字符串串删除了换行符,导致两行合并成一行。


sed 'N; s/System\nAdministrator/Desktop\nUser/; s/System Administrator/Desktop User/' gm3
The first meeting of the Linux Desktop
User's group will be held on Tuesday.
All Desktop Users should atted this meeting.
Thank you for your attendance.

第一个替换命令专门查找这两个要查找的单词间的换行,并将它放在了替换字符串中。


vi gm4

The first meeting of the Linux System
Administrator's group will be held on Tuesday.
All System Administrators should attend this meeting.


 sed 'N ; s/System\nAdministrator/Desktop\nUser/ ; s/System Administrator/Desktop User/' gm4
The first meeting of the Linux Desktop
User's group will be held on Tuesday.
All System Administrators should attend this meeting.

由于System Administator文本出现在了数据流中的最后一行,N命令会错过它,因为没有其他

行可读入到模式空间跟这行合并了。


可以将单行命令N放到命令前面,并将多行命令放到N命令后面:

sed 's/System Administrator/Desktop User/; N; s/System\nAdministrator/Desktop\nUser/' gm4
The first meeting of the Linux Desktop
User's group will be held on Tuesday.
All Desktop Users should attend this meeting.

删除数据流中出现在第一行前的空白行:

cat gm5 

This is the header line.
This is a data line.

This is the last line.


sed '/^$/{N; /header/D}' gm5
This is the header line.
This is a data line.

This is the last line.


sed编辑器脚本会查找空白行,然后利用N命令来将下一文本行添加到模式空间。

如果新的模式空间内容含有header单词,则D命令会删除模式空间的第一行。

如果不组合使用N命令和D命令,几乎不可能只删除第一个空白行而不删除其他他空白行。



3.多行删除命令


多行打印(print)命令p沿用了同样的方法,它只打印多行模式空间的第一行。这包括了

模式空间中直到换行符的所有字符。当你用-n选项来阻止脚本输出时,它和显示文本的

单行p命令的用法大同小异:

cat gm3
The first meeting of the Linux System
Administrator's group will be held on Tuesday.
All System Administrators should atted this meeting.
Thank you for your attendance.

sed -n 'N; /System\nAdministrator/P' gm3
The first meeting of the Linux System

当多行匹配出现时,P命令只会打印模式空间中的第一行。多行P命令的强大之处在和N

命令及D命令组合使用才显示出来。


D命令有个特性是会强制sed编辑返回到脚本的起始处,在同一模式空间重复执行这些命令

(它不会从数据流中读取新的文本行)。在命令脚本中加入N命令,你能单步扫过整个模式

空间,将多行一起匹配。

下一步,用P命令,你能打印出第一行,然后用D命令你能删除第一行并回环到脚本的起

处。一旦你回到了脚本的起始处,N命令会读取下一行文本并重新开始这个过程。这个循环

会一直继续下去直到数据流的结尾。




************************************************************
                           保持空间
************************************************************



模式空间(pattern space)是一块活动缓冲区,在sed编辑执行命令时它会保存sed编辑器

要校验的文本。


sed编辑器还利用了另一块缓冲区,称作保持空间(hold space)你可以在处理模式空间中

其他行时用保持空间来临时保存一些行。


sed编辑的保持空间命令:


h                将模式空间复制到保持空间

H                将模式空间附加到保持空间

g                将保持空间复制到模式空间

G                将保持空间附加到模式空间

x                交换模式空间和保持空间的内容




通常,在使用h或H命令将字符移动到保持空间后,最终你要用g,G或x命令将保存的字符串

移回到模式空间。

cat gm2
This is the header line.
This is the first data line.
This is the second data line.
This is the last line.


sed -n '/first/{
h
p
n
p
g
p
}' gm2
This is the first data line.
This is the second data line.
This is the first data line.


(1)sed脚本在地址中用正则表达式过滤出含有单词first的行;

(2)当有含有单词first的行出现时,h命令将该行放到保持空间;

(3)p命令打印模式空间也是就一个数据行的内容;

(4)n命令提取数据中的下一行(This is the second line),并将它放到模式空间;

(5)p命令打印模式空间的内容,现在是第二个数据行;

(6)g命令将保持空间的内容(This is the first data line)放回到模式空间,替换当前文本;

(7)p命令打印空间的当前内容,现在变回一个数据行了.


如果丢掉了一个p,打印顺序相反:

sed -n '/first/{
h
n
p
g
p
}' gm2
This is the second data line.
This is the first data line.




2.排除命令

  感叹命令(!)用来排除(negate)命令,也就是让原本起用的命令不起作用。



cat gm2
This is the header line.
This is the first data line.
This is the second data line.
This is the last line.



sed -n '/header/!p' gm2
This is the first data line.
This is the second data line.
This is the last line.




cat gm4
The first meeting of the Linux System
Administrator's group will be held on Tuesday.
All System Administrators should attend this meeting.


sed 'N; s/System.Administrator/Desktop User/' gm4
The first meeting of the Linux Desktop User's group will be held on Tuesday.
All System Administrators should attend this meeting.

sed  '$!N; s/System.Administrator/Desktop User/' gm4
The first meeting of the Linux Desktop User's group will be held on Tuesday.
All Desktop Users should attend this meeting.



反转数据流中的文本顺序。

(1)在模式空间中旋转第一行;

(2)将模式空间中行放到保持空间中;

(3)在模式空间中放入一下行;

(4)将保持空间附加到模式空间后;

(5)将模式空间中的所有内容放到保持空间中;

(6)~(9)重复执行(3)~(5)步,直到所有行都反序放到保持空间中;

(10)提取并打印行。


在使用这种方法时,你不想在处理时打印行。这意味着使用sed的-n命令选项。

下一步决定如何将保持空间文本附加到模式空间文本后面。这可以用G命令完成。唯一

的问题是你不想将保持空间附加到要处理的第一行文本后面。这可以用感叹命令解决:

1!G

下一步就是将新的模式空间(带附加反转的行的行)放到保持空间。需要用h命令

cat gm2
This is the header line.
This is the first data line.
This is the second data line.
This is the last line.

sed -n '{1!G; h; $p}' gm2
This is the last line.
This is the second data line.
This is the first data line.
This is the header line.



************************************************************
                           改变流
************************************************************

通常,sed编辑器会从脚本的顶部开始执行命令一直到处理脚本尾部(D命令是个例外,它

会强制sed编辑器返回到脚本顶部,而不是读取新的行)。sed编辑器提供了一个方法来改

变命令脚本的流,生成的结果类似于结构化编程环境的结果。



1.跳转

对数据流中的特定行执行一组命令:

跳转(branch)命令b格式如下:

[address]b [label]

address参数决定了哪些行或哪些行的数据会触发跳转命令。

label参数定义了要跳转到的位置。

如果没有加label参数,跳转命令会跳转到脚本的结尾:


cat gm2
This is the header line.
This is the first data line.
This is the second data line.
This is the last line.


sed '{2,3b; s/This is/Is this/; s/line/test?/}' gm2
Is this the header test?.
This is the first data line.
This is the second data line.
Is this the last test?.

跳转命令为数据流中的第2行和第3行跳过了那两个替换命令。


可以为跳转命令定义一个跳转到的会签,而不用直接跳转到脚本的尾部。

标签以冒号开始,最多可以有7个字符:

:label2

要指定标签,将它加到b命令就行。使用标签允许你在匹配的跳转地址跳过一些命令,

但仍然执行脚本中的其他命令:

cat gm2
This is the header line.
This is the first data line.
This is the second data line.
This is the last line.


sed '{/first/b jumb1; s/This is the/No jumb on/
:jumb1
s/This is the/Jumb here on/
}' gm2
No jumb on header line.
Jumb here on first data line.
No jumb on second data line.
No jumb on last line.


跳转命令指定如果匹配文本first出现在该行了,程序应该跳转到标签为jumb1的脚本行。

如果跳转命令模式没有匹配,sed编辑器会继续执行脚本中的命令,包括跳转标签后的命令

(所以,3个替换命令都会在不匹配跳转模式的行上执行)

echo "This, is, a, test, to, remove, commas." |sed -n '{:start; s/,//1p;b start}'
This is, a, test, to, remove, commas.
This is a, test, to, remove, commas.
This is a test, to, remove, commas.
This is a test to, remove, commas.
This is a test to remove, commas.
This is a test to remove commas.



脚本的每次迭代都会删除文本中的第第一个逗号,并打印字符串。

这个脚本有个问题:它永远不会结束。这就创建了一个无穷循环,会一直查找逗号,

直到最后你用crtl+c组合来给它发送一个信号,手动停止它。


#cho "This, is, a, to, remove, commas."|sed -n '{:start;s/,//1p;/,/b start}' 
This is, a, to, remove, commas.
This is a, to, remove, commas.
This is a to, remove, commas.
This is a to remove, commas.
This is a to remove commas.
#

现在在跳转命令只会在行中有逗号的情况下跳转。在最后一个逗号被删除后,跳转命令

不会再执行,脚本也能自己正常停止了。

2.测试

  类似于跳转命令,测试(test)命令t也用来改sed编辑器脚本的流。测试命令会基于替换

  命令的输出跳转到一个标签,而不是基于地址跳转到一个标签。


  如果替换命令成功匹配并替换了一个模式,测试命令就会跳转到指定的标签。如果替换

  命令未能匹配指定的模式,测试命令就不会跳转。

  格式:

  [address]t [label]

  跟跳转命令一样,在没有指定标签的情况下,如果测试成功,sed会跳转到脚本的结尾。


cat gm2
This is the header line.
This is the first data line.
This is the second data line.
This is the last line.

sed '{
s/first/matched/
t
s/This is the/No match on/
}' gm2
No match on header line.
This is the matched data line.
No match on second data line.
No match on last line.

第一个替换命令会查找模式文本first.如果它匹配了行中的模式,它会替换文本,而且

测试命令跳过后面的替换命令。如果第一个替换未能匹配模式,第二个命令会被执行。



使用测试命令,结束之前用跳转命令未能结束的循环:

echo "This, is, a, test, to, remove, commas." |sed -n '{:start s/,//1p; t start}'
This is, a, test, to, remove, commas.
This is a, test, to, remove, commas.
This is a test, to, remove, commas.
This is a test to, remove, commas.
This is a test to remove, commas.
This is a test to remove commas.


3.模式替代

echo "The cat sleeps in his hat." |sed 's/cat/"cat"/'
The "cat" sleeps in his hat.

在模式中使用通配符(.)来匹配多个单词
echo "The cat sleeps in his hat."|sed 's/.at/".at"/g'
The ".at" sleeps in his ".at".

替换字符串能点通配符号来匹配at前的一个字母。遗憾的是,替换字符字符串未能

匹配要匹配的单词的通配符。



4.and符号

sed 编辑器提供了一个解决方法。and符号(&)用来替换命令中的匹配模式。

不管匹配预定义模式是什么文本,你都能用and符号来在替代模式中调用它。

这让你可以操作匹配预定义模式的任何单词:

echo "The cat sleeps in his cat." |sed 's/.at/"&"/g' 
The "cat" sleeps in his "cat".

当模式匹配了单词cat,"cat"出现了替换后的单词里。

当它匹配了单词hat, "hat"就出现了在替换后的单词中。


5.替换单独的单词

  and符号会提取匹配替换命令中的指定模式的整个字符串。有时你只想提取这个字符串

  的一部分。

  sed编辑器用圆括号来定义替换模式的子字符串。然后你可以用替换模式中的特殊字符

  来引用每个子字符串。替换字符由反斜线和数字组成。数字表明子字符串模块的位置。

  sed编辑器会第一个模块分配字符\1,给第二模块分配字符\2。依此类推。


备注:当你在替换命令中使用圆括号时,你必须用转义字符来将它们识别为聚合字符而

      不是普通的圆括号。

echo "The System Administrator manual"|sed 's/\(System\) Administrator/\1 User/'
The System User manual

这个替换命令用一对圆括号将单词System括起来,从而将它识别字符串模块。然后它在替代

模式中使用\1来调用第一个识别的模块。



echo "That furry cat is pretty"|sed 's/furry \(.at\)/\1/'
That cat is pretty

echo "That furry hat is pretty"|sed 's/furry \(.at\)/\1/'
That hat is pretty

echo "1234567"|sed '{
:start
s/\(.*[0-9]\)\([0-9]\{3\}\)/\1,\2/
t start
}'
1,234,567

脚本匹配的模式分成了两个部分:

*[0-9]
[0-9]{3}

这个模式会查找两个子字符串。第一个子字符串是以数字结尾的任意长度的字符。

第二个字符串是一系列三位数字组成的块。如果这个模式在文本中找到了,替代文本

会在两个模块之间加一个逗号,每个模块都会通过其模块位置识别。


************************************************************
                          在脚本中使用sed
************************************************************

1.使用包装脚本

#!/bin/bash
#shell wrapper for sed editor script to reveres lines

sed -n '{
1!G
h
$p
}' $1

./reverse gm2
This is the last line.
This is the second data line.
This is the first data line.
This is the header line.



2.重定向sed输出
cat fact 
#!/bin/bash
#add commas to numbers in factorial answer

factorial=1
counter=1
number=$1

while [ $counter -le $number ]
do
  factorial=$[ $factorial * $counter ]
  counter=$[ $counter + 1 ]
done
reslut=`echo "$factorial" |sed '{ :start; s/\(.*[0-9]\)\([0-9]\{3\}\)/\1,\2/; t start}'`

echo "Result is $reslut"


./fact 20
Result is 2,432,902,008,176,640,000



3.创建sed实用工具


3.1加倍行距

cat gm2
This is the header line.
This is the first data line.
This is the second data line.
This is the last line.

#sed 'G' gm2
This is the header line.

This is the first data line.

This is the second data line.

This is the last line.

#

G会简单地将保持空间空间附加到模式空间内容后。当你启动sed编辑器时,保持空间只有一个空行。

将它附加到已有行后面。

这个脚本在数据流的最后一行后面也加了一行空白行,使得文件末尾也产生一个行空白行。

如果你不想要这个空白行,你可以使用排除符号(!)和尾行符号($)来确保脚本不会将空白行

加到数据流的最后一行后:


#sed '$!G' gm2
This is the header line.

This is the first data line.

This is the second data line.

This is the last line.
#



3.2对可能含有空白行的文件加倍行间距

vi gm6

This is line one.
This is line two.


This is line three.
this is line four.

#sed '$!G' gm6
This is line one.

This is line two.





This is line three.

this is line four.
#

现在在原来的空白行的位置有3个空白行。这个问题解决办法是,首先删除数据中的所有空白行,然

后G命令在所有行后插入新的空白行。 需要将d和一个匹配空白行的模式一起使用:

/^$/d

#sed '/^$/d;$!G' gm6
This is line one.

This is line two.

This is line three.

this is line four.
#

3.3给文件中的行编号

 "="显示数据流中行的行号:


sed '/^$/d;$!G;=' gm6
1
This is line one.

2
This is line two.

5
This is line three.

6
this is line four.


cat gm2
This is the header line.
This is the first data line.
This is the second data line.
This is the last line.

sed '=' gm2
1
This is the header line.
2
This is the first data line.
3
This is the second data line.
4
This is the last line.

解决办法:是将行号和文本放在同一行。


一旦你有了等号命令输出,你可以将输出管道输出给另一个sed编辑脚本,它会用N命令来合并这两行。

 sed '=' gm2 |sed 'N; s/\n/ /'
1 This is the header line.
2 This is the first data line.
3 This is the second data line.
4 This is the last line.



3.4打印末尾行

  用p命令来打印数据流中所有的行号或匹配某个特定模式的行。

  如果你要处理一个长输出(比如日志文件)中的末尾几行,怎么办?

  美元符($)代表数据流中最后一行。


cat gm2
This is the header line.
This is the first data line.
This is the second data line.
This is the last line.

sed -n '$p' gm2
This is the last line.

那么,如何用美元符来显示数据流末尾的若干行呢?答案是创建滚动窗口(rolling windows)

滚动窗口是查验模式空间中文本行组成的块常用方法,它会用N命令将它们合并起来。

N命令会将下一行文本附加到已在模式中的文本行后面。一旦你在模式空间有了一块10行的文本

你可以用美元符来检查你是否在数据的尾部。如果你不在结尾,就继续向模式空间增加行,并删除

原来的行(记住D命令,它会删除模式空间的第一行)。

通过N命令循环和D命令,你向模式空间的文本行块增加了新行,同时也删除了旧行。跳转命令会完美

适用于这个循环。要结束循环,只要识别最一些并用Q命令退出就可以。


sed '{
:start
$q
N
11,$D
b start
}' /etc/passwd 
ntp:x:38:38::/etc/ntp:/sbin/nologin
apache:x:48:48:Apache:/var/www:/sbin/nologin
saslauth:x:498:76:"Saslauthd user":/var/empty/saslauth:/sbin/nologin
postfix:x:89:89::/var/spool/postfix:/sbin/nologin
pulse:x:497:496:PulseAudio System Daemon:/var/run/pulse:/sbin/nologin
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
tcpdump:x:72:72::/:/sbin/nologin
mockbuild:x:504:504::/home/mockbuild:/bin/bash
laomeng:x:505:505::/home/laomeng:/bin/bash
qemu:x:107:107:qemu user:/:/sbin/nologin

这个脚本首先检查这行是不是数据流中最后一行。如果是,退出(quit)命令就停止循环。

N命令会将下一行附加到模式空间的当前行后。如果当前行在10后面,11,$D会删除模式空间中的

第一行。



************************************************************
                          删除行
************************************************************


1.删除连续的空白行

  删除连续的空白行最简单的方法是用地址区来检查数据流。

  /./,/^$/!d

  区间是/./到/^$/。区间的开始地址会匹配任何含有至少一个字符的行。区间的

  结束地址会匹配一个空行。

cat gm6
This is line one.
This is line two.


This is line three.
this is line four.

sed '/./,/^$/!d' gm6
This is line one.
This is line two.

This is line three.
this is line four.


2.删除开头的空白行

/./,$!d

这个脚本用地址区间来决定哪行删掉,这个区间从含有字符的行开始,一直到数据流结束。

#vi gm7



This is the first line.

This is the second line.
#

sed '/./,$!d' gm7
This is the first line.

This is the second line.



3.删除结尾的空白行

  删除结尾的空白行并像删除开头空白行那么容易。就跟打印数据流的结尾一样,


  sed '{
  :start
  /^\n*$/{$d; N; b start}
  }' 

#vi gm8

This is the first line.
This is the second line.



~
#

sed '{
> :start
> /^\n*$/{$d; N; b start}
> }' gm8
This is the first line.
This is the second line.



4.删除html标签


vi gm9



 This is the page title</titl>
</head>
<body>
<p>
This is teh <b>first</b> line in the web page. This should provide
some <i>useful</i> information for us to use in our shell script
</body>
<html>


#sed '</span>s<span class="hljs-regexp">/<.*>/</span>/g<span class="hljs-string">' gm9






This is teh  line in the web page. This should provide
some  information for us to use in our shell script


[root@Jackm Laomeng]# 


#sed '</span>s<span class="hljs-regexp">/<[^>]*>/</span>/g<span class="hljs-string">' gm9


 This is the page title



This is teh first line in the web page. This should provide
some useful information for us to use in our shell script


[root@Jackm Laomeng]# 


sed '</span>s<span class="hljs-regexp">/<[^>]*>/</span><span class="hljs-regexp">/g; /</span>^$/d<span class="hljs-string">' gm9
 This is the page title
This is teh first line in the web page. This should provide
some useful information for us to use in our shell script
[root@Jackm Laomeng]# 




#################################################################################
#                               gawk进阶                                        #
#################################################################################

gawk支持两种变量:

  1.内建变量
  2.自定义变量


1.1字和数据行分隔符变量

    数据字段变量允许你使用美元符号($)和数据字段行中位置对应的数值来引用该数据中的字段。

    变量$1;引用第二个变量$2,依次类推


    字段是由分隔符来划定的。字段分隔符是一个空白符,也就是空格或制表符(table)



    gawk数据字段和数据行变量

    FILEDWIDTHS     由空格分隔开的定义了每个数据字段确切宽度的一列数字

    FS               输入字段分隔符

    RS               输入数据行分隔符

    OFS              输出字体分隔符

    ORS              输出数据行分隔符


变量FS和OFS定义了gawk如何处理数据流中的数据字段。

print $1 ,$2 ,$3



cat gm1
data11,data12,data13,data14,data15
data21,data22,data23,data24,data25
data31,data32,data33,data34,data35


gawk '</span>BEGIN{FS=<span class="hljs-string">","</span>}{<span class="hljs-built_in">print</span> $<span class="hljs-number">1</span>,$<span class="hljs-number">2</span>,$<span class="hljs-number">3</span>}<span class="hljs-string">' gm1
data11 data12 data13
data21 data22 data23
data31 data32 data33


gawk '</span>BEGIN{FS=<span class="hljs-string">","</span>; OFS=<span class="hljs-string">"-"</span>}{<span class="hljs-built_in">print</span> $<span class="hljs-number">1</span>,$<span class="hljs-number">2</span>,$<span class="hljs-number">3</span>}<span class="hljs-string">' gm1 
data11-data12-data13
data21-data22-data23
data31-data32-data33

gawk '</span>BEGIN{FS=<span class="hljs-string">","</span>; OFS=<span class="hljs-string">"---"</span>}{<span class="hljs-built_in">print</span> $<span class="hljs-number">1</span>,$<span class="hljs-number">2</span>,$<span class="hljs-number">3</span>}<span class="hljs-string">' gm1
data11---data12---data13
data21---data22---data23
data31---data32---data33

gawk '</span>BEGIN{FS=<span class="hljs-string">","</span>; OFS=<span class="hljs-string">"<-->"</span>}{<span class="hljs-built_in">print</span> $<span class="hljs-number">1</span>,$<span class="hljs-number">2</span>,$<span class="hljs-number">3</span>}<span class="hljs-string">' gm1
data11<-->data12<-->data13
data21<-->data22<-->data23
data31<-->data32<-->data33


vi gm1b

1005.324756.37
115-2.349194.00
05810.1298100.1


gawk '</span>BEGIN{FIELDWIDTHS=<span class="hljs-string">"3 5 2 5"</span>}{<span class="hljs-built_in">print</span> $<span class="hljs-number">1</span>,$<span class="hljs-number">2</span>,$<span class="hljs-number">3</span>,$<span class="hljs-number">4</span>}<span class="hljs-string">' gm1b
100 5.324 75 6.37
115 -2.34 91 94.00
058 10.12 98 100.1


cat laomeng2
Riley Mullen
123 Main Street
Chicago, IL 6061
(312)555-1234


Frank Williams
456 Oak Street
Indianapolis, IN 46201
(317)555-9876

Heley Snell
4231 Elm Street
Detroit, MI 48201
(313)555-4938

gawk '</span>BEGIN{FS=<span class="hljs-string">"\n"</span> ; RS=<span class="hljs-string">""</span>}{<span class="hljs-built_in">print</span> $<span class="hljs-number">1</span>,$<span class="hljs-number">4</span>}<span class="hljs-string">' laomeng2
Riley Mullen (312)555-1234
Frank Williams (317)555-9876
Heley Snell (313)555-4938



2.数据变量

 ARGC           当前命令行参数个数

 ARGIND         当前文件在ARGV中的位置

 ARGV           包含命令行参数的数组

 CONVFMT        数字的转换格式;默认值为:%.6 g

 ENVIRON        当前shell环境变量及其值组成的关联数组

 FILENAME       用作gawk输入数据的数据文件的文件名

 ERRNO          当读取或关闭输入文件发生错误时的系统错误号

 FNR            当前数据文件中的数据行数

 IGNORECASE     设成非零值时,忽略gawk命令中出现的字符串的字符大小写

 NF             数据文件中的字段总数

 NR             已处理的输入数据行数目

 OFMT           数字的输出格式;默认值为%.6 g

 RLENGTH        由math函数所匹配的子字符串的长度

 RSTART         由math函数所匹配的子字符串的起始位置


gawk '</span>BEGIN{<span class="hljs-built_in">print</span>  ARGC,ARGV[<span class="hljs-number">1</span>]}<span class="hljs-string">' gm1
2 gm1

ARGC变量表明命令行上两个参数。这个包括gawk命令和guamei1参数(记住,程序脚本不算参数

)。ARGV数组从代表该命令的索引0开始,第一个数组值是gawk命令后的第一个命令行参数。



ENVIRON变量它使用关联数组来提取shell环境变量。关联数组用作文本作为数组的索引值,而不可用数值。

gawk '</span>BEGIN{
> <span class="hljs-built_in">print</span> ENVIRON[<span class="hljs-string">"HOME"</span>]
> <span class="hljs-built_in">print</span> ENVIRON[<span class="hljs-string">"PATH"</span>]
> }<span class="hljs-string">' /home/laomeng
/home/laomeng
/usr/lib64/qt-3.3/bin:/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin:/home/laomeng/bin


ENVIRON["HOME"]变量从shell中提取HOME环境变量的值。类似地,ENVIRON["PATH"]提取了PATH环境变量的值。

你可以用这种方法从shell中提取任何环境变量的值来在gawk程序中使用。

当你要在gawk程序中记录数据字段和数据行时,FNR,NF和NR就能可以使用上。

有时你不知道数据行中到底有多少个字段。NF变量允许你指定数据行的中最后一个数据字段,而不用知道它的具体位置:

gawk '</span>BEGIN{FS=<span class="hljs-string">":"</span>; OFS=<span class="hljs-string">":"</span>}{<span class="hljs-built_in">print</span> $<span class="hljs-number">1</span>,$NF}<span class="hljs-string">' /etc/passwd


 gawk '</span>BEGIN{FS=<span class="hljs-string">":"</span>; OFS=<span class="hljs-string">":"</span>}{<span class="hljs-built_in">print</span> $<span class="hljs-number">1</span>,$NF}<span class="hljs-string">' /etc/passwd
root:/bin/bash
bin:/sbin/nologin
daemon:/sbin/nologin
adm:/sbin/nologin
.................
pulse:/sbin/nologin
sshd:/sbin/nologin
tcpdump:/sbin/nologin
mockbuild:/bin/bash
qemu:/sbin/nologin
laomeng:/bin/bash


NF变量含有数据文件中最后一个数据字段的数据值。


FNR和NR变量彼此类似,但略有不同。FNR变量含有处理过的当前数据文件中的数据行总数,

NF变量则含有处理过数据文件数据行总数:



 cat gm1
data11,data12,data13,data14,data15
data21,data22,data23,data24,data25
data31,data32,data33,data34,data35


gawk  '</span>BEGIN{FS=<span class="hljs-string">","</span>}{<span class="hljs-built_in">print</span> $<span class="hljs-number">1</span>,<span class="hljs-string">"FNR="</span>FNR}<span class="hljs-string">' gm1 gm1
data11 FNR=1
data21 FNR=2
data31 FNR=3
data11 FNR=1
data21 FNR=2
data31 FNR=3

gawk  '</span>BEGIN{FS=<span class="hljs-string">","</span>}{<span class="hljs-built_in">print</span> $<span class="hljs-number">1</span>,<span class="hljs-string">"NR="</span>NR}<span class="hljs-string">' gm1 gm1
data11 NR=1
data21 NR=2
data31 NR=3
data11 NR=4
data21 NR=5
data31 NR=6


gawk '</span>
BEGIN{FS=<span class="hljs-string">","</span>}
{<span class="hljs-built_in">print</span> $<span class="hljs-number">1</span>, <span class="hljs-string">"FNR="</span>FNR, <span class="hljs-string">"NR="</span>NR}
END{<span class="hljs-built_in">print</span> <span class="hljs-string">"There wre "</span>,NR,<span class="hljs-string">" records processed"</span>}<span class="hljs-string">' gm1 gm1


gawk '</span>
> BEGIN{FS=<span class="hljs-string">","</span>}
> {<span class="hljs-built_in">print</span> $<span class="hljs-number">1</span>, <span class="hljs-string">"FNR="</span>FNR, <span class="hljs-string">"NR="</span>NR}
> END{<span class="hljs-built_in">print</span> <span class="hljs-string">"There wre "</span>,NR,<span class="hljs-string">" records processed"</span>}<span class="hljs-string">' gm1 gm1
data11 FNR=1 NR=1
data21 FNR=2 NR=2
data31 FNR=3 NR=3
data11 FNR=1 NR=4
data21 FNR=2 NR=5
data31 FNR=3 NR=6
There wre  6  records processed


FNR变量的值在gawk处理第二个数据文件时被重置了,而NR变量则在进入第二个数据文件后

继续计数。结果是,如果只用使用一个数据文件时作为输入,那么FNR和NR的值将会相同。

如果使用多个数据文件作为输入,那么FNR的值会在处理每个数据文件时被重置,而NR值则会

继续计数直到处理完成所有的数据文件。


2.1.1自定义变量

   gawk自定义变量可以是任意数目的字母,数字和下划线,但不能以数字开关。

   gawk变量名区分大小写。


(1)在脚本中给变量赋值

gawk '</span>
BEGIN{
testing=<span class="hljs-string">"This is a test"</span>
<span class="hljs-built_in">print</span> testing
}<span class="hljs-string">'

gawk '</span>
> BEGIN{
> testing=<span class="hljs-string">"This is a test"</span>
> <span class="hljs-built_in">print</span> testing
> }<span class="hljs-string">'
This is a tes

print语句的输出是testing变量的当前值。


gawk变量可以保存数值和文件值:

gawk '</span>
BEGIN{
testing=<span class="hljs-string">"This is a test"</span>
<span class="hljs-built_in">print</span> testing
testing=<span class="hljs-number">45</span>
<span class="hljs-built_in">print</span> testing
}<span class="hljs-string">'



gawk '</span>
> BEGIN{
> testing=<span class="hljs-string">"This is a test"</span>
> <span class="hljs-built_in">print</span> testing
> testing=<span class="hljs-number">45</span>
> <span class="hljs-built_in">print</span> testing
> }<span class="hljs-string">'
This is a test
45


赋值语句还可以包含数学表达式来处理数字值:

gawk '</span>BEGIN{x=<span class="hljs-number">4</span>; x= x + <span class="hljs-number">2</span>; <span class="hljs-built_in">print</span> x }<span class="hljs-string">'

gawk '</span>BEGIN{x=<span class="hljs-number">4</span>; x= x + <span class="hljs-number">2</span>; <span class="hljs-built_in">print</span> x }<span class="hljs-string">'
6


(2)在命令行上给变量赋值

vi script1

BEGIN{FS=","}
{print $n}


gawk -f script1 n=2 gm1
data12
data22
data32


gawk -f script1 n=3 gm1
data13
data23
data33

vi script2

BEGIN{print "The starting value is" ,n; FS=","}
{print $2}

gawk -f script2 n=3 gm1 
The starting value is 
data12
data22
data32


gawk -v n=3 -f script2 gm1
The starting value is 3
data12
data22
data32


2.1.2处理数组


  关联数组跟数字数组不同之处在于它的索引值可以是任意文本字符串。

  你不需要用连续数字来标识数组中的数据元素。相反关联数组用各种字符串来引用值。

  每个索引都必须是唯一的,并唯一地标识给它赋给它的数据元素。


(1)定义数组变量

格式:var[index] = element

其中var是变量名,index是关联数组的索引值,elemnt是数据元素。


capital["Illinois"] = "Springfield"
capital["Indiana"] =  "Indianpolis"
capital["Ohio"] = "Columbus"

在引用数组变量时,必须包含索引值来提取相应的数据元素值:

gawk '</span>BEGIN{
capital[<span class="hljs-string">"Illionios"</span>] = <span class="hljs-string">"Springfield"</span>
<span class="hljs-built_in">print</span> capital[<span class="hljs-string">"Illionios"</span>]
}<span class="hljs-string">'


gawk '</span>BEGIN{
> capital[<span class="hljs-string">"Illionios"</span>] = <span class="hljs-string">"Springfield"</span>
> <span class="hljs-built_in">print</span> capital[<span class="hljs-string">"Illionios"</span>]
> }<span class="hljs-string">'
Springfield



在引用数组变量时,数据元素的值会出现。数据元素值是数字值时也一样:

gawk '</span>BEGIN{
<span class="hljs-reserved">var</span>[<span class="hljs-number">1</span>] = <span class="hljs-number">34</span>
<span class="hljs-reserved">var</span>[<span class="hljs-number">2</span>] = <span class="hljs-number">3</span>
total = <span class="hljs-reserved">var</span>[<span class="hljs-number">1</span>] + <span class="hljs-reserved">var</span>[<span class="hljs-number">2</span>]
<span class="hljs-built_in">print</span> total
}<span class="hljs-string">'


gawk '</span>BEGIN{
> <span class="hljs-reserved">var</span>[<span class="hljs-number">1</span>] = <span class="hljs-number">34</span>
> <span class="hljs-reserved">var</span>[<span class="hljs-number">2</span>] = <span class="hljs-number">3</span>
> total = <span class="hljs-reserved">var</span>[<span class="hljs-number">1</span>] + <span class="hljs-reserved">var</span>[<span class="hljs-number">2</span>]
> <span class="hljs-built_in">print</span> total
> }<span class="hljs-string">'
37


2.1.3遍历数组变量

  关联数组变量的问题在于你可能无法知晓索引值是什么。跟使用连续数字作为索引值的

  数字数组不同,关联数组的索引可以是任何东西。

  在gawk中遍历一个关联数组:

  for ( var in array)
  {
    statements
  }

  这个for语句会在每次将关联数组array的下一个索引值赋给变量var时,执行一遍statements。

  重要的是记住这个变量是索引值而不是数组元素值。

  gawk '</span>BEGIN{
  <span class="hljs-reserved">var</span>[<span class="hljs-string">"a"</span>] = <span class="hljs-number">1</span>
  <span class="hljs-reserved">var</span>[<span class="hljs-string">"g"</span>] = <span class="hljs-number">2</span>
  <span class="hljs-reserved">var</span>[<span class="hljs-string">"m"</span>] = <span class="hljs-number">3</span>
  <span class="hljs-reserved">var</span>[<span class="hljs-string">"u"</span>] = <span class="hljs-number">4</span>
  <span class="hljs-keyword">for</span> ( laomeng <span class="hljs-keyword">in</span> <span class="hljs-reserved">var</span>)
  {
    <span class="hljs-built_in">print</span> <span class="hljs-string">"Index:"</span> ,laomeng, <span class="hljs-string">"- Value:"</span>,<span class="hljs-reserved">var</span>[laomeng]
  }
  }<span class="hljs-string">' |sort -n


  gawk '</span>BEGIN{
>   <span class="hljs-reserved">var</span>[<span class="hljs-string">"a"</span>] = <span class="hljs-number">1</span>
>   <span class="hljs-reserved">var</span>[<span class="hljs-string">"g"</span>] = <span class="hljs-number">2</span>
>   <span class="hljs-reserved">var</span>[<span class="hljs-string">"m"</span>] = <span class="hljs-number">3</span>
>   <span class="hljs-reserved">var</span>[<span class="hljs-string">"u"</span>] = <span class="hljs-number">4</span>
>   <span class="hljs-keyword">for</span> ( laomeng <span class="hljs-keyword">in</span> <span class="hljs-reserved">var</span>)
>   {
>     <span class="hljs-built_in">print</span> <span class="hljs-string">"Index:"</span> ,laomeng, <span class="hljs-string">"- Value:"</span>,<span class="hljs-reserved">var</span>[laomeng]
>   }
>   }<span class="hljs-string">' 
Index: u - Value: 4
Index: m - Value: 3
Index: a - Value: 1
Index: g - Value: 2

索引值不会按任何特定的顺序返回,但它们每个都会有个对应的数据元素值。

gawk '</span>BEGIN{
>   <span class="hljs-reserved">var</span>[<span class="hljs-string">"a"</span>] = <span class="hljs-number">1</span>
>   <span class="hljs-reserved">var</span>[<span class="hljs-string">"g"</span>] = <span class="hljs-number">2</span>
>   <span class="hljs-reserved">var</span>[<span class="hljs-string">"m"</span>] = <span class="hljs-number">3</span>
>   <span class="hljs-reserved">var</span>[<span class="hljs-string">"u"</span>] = <span class="hljs-number">4</span>
>   <span class="hljs-keyword">for</span> ( laomeng <span class="hljs-keyword">in</span> <span class="hljs-reserved">var</span>)
>   {
>     <span class="hljs-built_in">print</span> <span class="hljs-string">"Index:"</span> ,laomeng, <span class="hljs-string">"- Value:"</span>,<span class="hljs-reserved">var</span>[laomeng]
>   }
>   }<span class="hljs-string">' |sort -n
Index: a - Value: 1
Index: g - Value: 2
Index: m - Value: 3
Index: u - Value: 4


2.1.4删除数组变量

  从关联数组中删除数组索引要用一个特别的命令:

  delete array[index] #删除命令会从数组中删除关联索引值和相关元素值。

gawk '</span>BEGIN{
<span class="hljs-reserved">var</span>[<span class="hljs-string">"a"</span>] = <span class="hljs-number">1</span>
<span class="hljs-reserved">var</span>[<span class="hljs-string">"g"</span>] = <span class="hljs-number">2</span>
<span class="hljs-keyword">for</span> (laomeng <span class="hljs-keyword">in</span> <span class="hljs-reserved">var</span>)
{
  <span class="hljs-built_in">print</span> <span class="hljs-string">"Index:"</span>,laomeng, <span class="hljs-string">"- Value:"</span>,<span class="hljs-reserved">var</span>[laomeng]
}
<span class="hljs-keyword">delete</span> <span class="hljs-reserved">var</span>[<span class="hljs-string">"g"</span>]
<span class="hljs-built_in">print</span> <span class="hljs-string">"---"</span>
<span class="hljs-keyword">for</span> (laomeng <span class="hljs-keyword">in</span> <span class="hljs-reserved">var</span>)
{
  <span class="hljs-built_in">print</span> <span class="hljs-string">"Index:"</span>,laomeng, <span class="hljs-string">"- Value:"</span>,<span class="hljs-reserved">var</span>[laomeng]
}
}<span class="hljs-string">'


gawk '</span>BEGIN{
> <span class="hljs-reserved">var</span>[<span class="hljs-string">"a"</span>] = <span class="hljs-number">1</span>
> <span class="hljs-reserved">var</span>[<span class="hljs-string">"g"</span>] = <span class="hljs-number">2</span>
> <span class="hljs-keyword">for</span> (laomeng <span class="hljs-keyword">in</span> <span class="hljs-reserved">var</span>)
> {
>   <span class="hljs-built_in">print</span> <span class="hljs-string">"Index:"</span>,laomeng, <span class="hljs-string">"- Value:"</span>,<span class="hljs-reserved">var</span>[laomeng]
> }
> <span class="hljs-keyword">delete</span> <span class="hljs-reserved">var</span>[<span class="hljs-string">"g"</span>]
> <span class="hljs-built_in">print</span> <span class="hljs-string">"---"</span>
> <span class="hljs-keyword">for</span> (laomeng <span class="hljs-keyword">in</span> <span class="hljs-reserved">var</span>)
> {
>   <span class="hljs-built_in">print</span> <span class="hljs-string">"Index:"</span>,laomeng, <span class="hljs-string">"- Value:"</span>,<span class="hljs-reserved">var</span>[laomeng]
> }
> }<span class="hljs-string">'
Index: a - Value: 1
Index: g - Value: 2
---
Index: a - Value: 1

一旦关联数组中删除了索引值,你就无法再提取它了。


3.1使用模式

 BGEGIN 
 END


3.1.1正则表达工


cat gm1
data11,data12,data13,data14,data15
data21,data22,data23,data24,data25
data31,data32,data33,data34,data35

gawk '</span>BEGIN{FS=<span class="hljs-string">","</span>} <span class="hljs-regexp">/11/</span>{<span class="hljs-built_in">print</span> $<span class="hljs-number">1</span>}<span class="hljs-string">' gm1


gawk '</span>BEGIN{FS=<span class="hljs-string">","</span>} <span class="hljs-regexp">/11/</span>{<span class="hljs-built_in">print</span> $<span class="hljs-number">1</span>}<span class="hljs-string">' gm1
data11


gawk '</span>BEGIN{FS=<span class="hljs-string">","</span>} <span class="hljs-regexp">/.d/</span>{<span class="hljs-built_in">print</span> $<span class="hljs-number">1</span>}<span class="hljs-string">' gm1
data11
data21
data31


3.1.2匹配操作符

  匹配操作符(mathing operator)允许将正则表达限定在数据行中的特定数据字段。

  匹配操作符是波浪线(~)。你要一起指定匹配操作符中,数据字段变量及要匹配的正则表达式:

  $1 ~ /^date/

  $1变量代表数据行中的第一个数据字段。这个表达式会过滤出第一个字段以文本data开头的

  所有数据行。

gawk '</span>BEGIN{FS=<span class="hljs-string">","</span>} $<span class="hljs-number">2</span> ~ <span class="hljs-regexp">/^data2/</span>{<span class="hljs-built_in">print</span> $<span class="hljs-number">0</span>}<span class="hljs-string">' gm1
data21,data22,data23,data24,data25

匹配操作符会正则表达式/^data2/来匹配第二个数据字段,该正则表达指明字符串要以

文本data2开头。


gawk -F: '</span>$<span class="hljs-number">1</span> ~ <span class="hljs-regexp">/laomeng/</span>{<span class="hljs-built_in">print</span> $<span class="hljs-number">0</span>,$NF}<span class="hljs-string">' /etc/passwd
laomeng:x:505:0::/home/laomeng:/bin/bash /bin/bash

第一个数据字段中查找文本laomeng。当它在数据行找到了这个模式时,

它会打印数据行的第一个和最后一个数据字段值。


可以用!符号来排除正则表达式的匹配:

$1 !~ /expression/

gawk -F: '</span>$<span class="hljs-number">1</span> !~ <span class="hljs-regexp">/laomeng/</span>{<span class="hljs-built_in">print</span> $<span class="hljs-number">1</span>,$NF}<span class="hljs-string">' /etc/passwd
root /bin/bash
bin /sbin/nologin
daemon /sbin/nologin
adm /sbin/nologin
lp /sbin/nologin
sync /bin/sync
shutdown /sbin/shutdown
.............
sshd /sbin/nologin
tcpdump /sbin/nologin
mockbuild /bin/bash
qemu /sbin/nologin


3.1.3数学表达式


gawk -F: '</span>$<span class="hljs-number">4</span> == <span class="hljs-number">0</span>{<span class="hljs-built_in">print</span> $<span class="hljs-number">1</span>}<span class="hljs-string">' /etc/passwd
root
sync
shutdown
halt
operator
laomeng  #//前5系统默认用户

该脚本会查看第4个字段含有值0的数据行。在linux系统中,有5个用户的账户属于root
用户组。

数学表达式:

x == y: 值x等于y.

x <= y: 值x小于等于y.

x < y:  值x小于y.

x >= y: 值x大于等于y.

x > y:  值x大于y.


 cat gm1
data11,data12,data13,data14,data15
data21,data22,data23,data24,data25
data31,data32,data33,data34,data35

gawk -F, '</span>$<span class="hljs-number">1</span> == <span class="hljs-string">"data"</span>{<span class="hljs-built_in">print</span> $<span class="hljs-number">1</span>}<span class="hljs-string">' gm1   #无匹配输出结果


gawk -F, '</span>$<span class="hljs-number">1</span> == <span class="hljs-string">"data11"</span>{<span class="hljs-built_in">print</span> $<span class="hljs-number">1</span>}<span class="hljs-string">' gm1
data11




3.1结构化命令


3.1.1 if语句

gawk编程语句语言支持标准的if-then-else格式的if语句。你必须为if语句定义一个评估条件,

并将其用圆括号括起来。如果条件评估为TRUE,紧跟在if语句后的语句会执行。如果条件评估

FALSE,那这条语句就会被跳过。格式:

if (condition)
   statement1

或
if (conditon) statement1


cat gm4
10
5
13
50
34


gawk '</span>{<span class="hljs-keyword">if</span> ($<span class="hljs-number">1</span> > <span class="hljs-number">20</span>) <span class="hljs-built_in">print</span> $<span class="hljs-number">1</span>}<span class="hljs-string">' gm4 #文件行第一个字段大于20输出
50
34


gawk '</span>{
<span class="hljs-keyword">if</span> ( $<span class="hljs-number">1</span> > <span class="hljs-number">20</span>)
{
  x = $<span class="hljs-number">1</span> * <span class="hljs-number">2</span>
  <span class="hljs-built_in">print</span> x
}
}<span class="hljs-string">' gm4

gawk '</span>{
> <span class="hljs-keyword">if</span> ( $<span class="hljs-number">1</span> > <span class="hljs-number">20</span>)
> {
>   x = $<span class="hljs-number">1</span> * <span class="hljs-number">2</span>
>   <span class="hljs-built_in">print</span> x
> }
> }<span class="hljs-string">' gm4
100
68


gawk的if语句也支持else语句,允许在if语句条件不成立的情况下执行一条或多条语句。

gawk '</span>{
<span class="hljs-keyword">if</span> ( $<span class="hljs-number">1</span> > <span class="hljs-number">20</span> )
{
   x = $<span class="hljs-number">1</span> *<span class="hljs-number">2</span>
   <span class="hljs-built_in">print</span> x
}
<span class="hljs-keyword">else</span>
{
  x = $<span class="hljs-number">1</span> /<span class="hljs-number">2</span>
  <span class="hljs-built_in">print</span> x
}
}<span class="hljs-string">'  gm4 


gawk '</span>{
> <span class="hljs-keyword">if</span> ( $<span class="hljs-number">1</span> > <span class="hljs-number">20</span> )
> {
>    x = $<span class="hljs-number">1</span> *<span class="hljs-number">2</span>
>    <span class="hljs-built_in">print</span> x
> }
> <span class="hljs-keyword">else</span>
> {
>   x = $<span class="hljs-number">1</span> /<span class="hljs-number">2</span>
>   <span class="hljs-built_in">print</span> x
> }
> }<span class="hljs-string">' gm4
5
2.5
6.5
100
68


可以在单行上使用else子句,但必须在if语句部分之后使用分号:

if (condition) statement1; else statement2

cat gm4
10
5
13
50
34


gawk '</span>{<span class="hljs-keyword">if</span> ($<span class="hljs-number">1</span> > <span class="hljs-number">20</span>) <span class="hljs-built_in">print</span> $<span class="hljs-number">1</span> * <span class="hljs-number">2</span>;<span class="hljs-keyword">else</span> <span class="hljs-built_in">print</span> $<span class="hljs-number">1</span> /<span class="hljs-number">2</span>}<span class="hljs-string">' gm4
5
2.5
6.5
100
68


3.1.2 while语句

 while语句为gawk程序提供了一个基本的的循环功能。格式:

 while (condition)
 {
    statements
 }


while循环允许遍历一组数组,并检查结果结束的迭代的条件。在计算中必须使用每个数据行中的

多个数值时,它能帮得上忙:


cat gm5
130 120 135
160 113 140
145 170 215

gawk '</span>{
total = <span class="hljs-number">0</span>
i = <span class="hljs-number">1</span>
<span class="hljs-keyword">while</span> (i < <span class="hljs-number">4</span>)
{
  total += $i
  i++
}
avg = total / <span class="hljs-number">3</span>
<span class="hljs-built_in">print</span> <span class="hljs-string">"Avarager:"</span>,avg
}<span class="hljs-string">' gm5



gawk编程语言支持在while循环中使用break和continue语句,允许从循环中跳出:

cat gm5
130 120 135
160 113 140
145 170 215

gawk '</span>{
total = <span class="hljs-number">0</span>
i =  <span class="hljs-number">1</span>
<span class="hljs-keyword">while</span> ( i < <span class="hljs-number">4</span> )
{
   total += $i
   <span class="hljs-keyword">if</span> ( i == <span class="hljs-number">2</span> )
      <span class="hljs-keyword">break</span>
    i++
}
avg = total / <span class="hljs-number">2</span>
<span class="hljs-built_in">print</span> <span class="hljs-string">"The average of the first two date elments is:"</span>,avg
}<span class="hljs-string">' gm5

gawk '</span>{
> total = <span class="hljs-number">0</span>
> i =  <span class="hljs-number">1</span>
> <span class="hljs-keyword">while</span> ( i < <span class="hljs-number">4</span> )
> {
>    total += $i
>    <span class="hljs-keyword">if</span> ( i == <span class="hljs-number">2</span> )
>       <span class="hljs-keyword">break</span>
>     i++
> }
> avg = total / <span class="hljs-number">2</span>
> <span class="hljs-built_in">print</span> <span class="hljs-string">"The average of the first two date elments is:"</span>,avg
> }<span class="hljs-string">' gm5
The average of the first two date elments is: 125
The average of the first two date elments is: 136.5
The average of the first two date elments is: 157.5

break语句用来在i变量的值为2时从while循环中跳出。


3.1.3 do-whlie语句

do-while语句类似while语句,但会在检查条件语句之前执行命令。格式:

do
{
  statements
}while (condition)

cat gm5
130 120 135
160 113 140
145 170 215

gawk '</span>{
total = <span class="hljs-number">0</span> 
i = <span class="hljs-number">1</span>
<span class="hljs-keyword">do</span>
{
  total += $i
  i++
}<span class="hljs-keyword">while</span> (total < <span class="hljs-number">150</span>)
<span class="hljs-built_in">print</span> <span class="hljs-string">"The total value is:"</span>,total
}<span class="hljs-string">' gm5


gawk '</span>{
> total = <span class="hljs-number">0</span> 
> i = <span class="hljs-number">1</span>
> <span class="hljs-keyword">do</span>
> {
>   total += $i
>   i++
> }<span class="hljs-keyword">while</span> (total < <span class="hljs-number">150</span>)
> <span class="hljs-built_in">print</span> <span class="hljs-string">"The total value is:"</span>,total
> }<span class="hljs-string">' gm5
The total value is: 250
The total value is: 160
The total value is: 315


4.1 for语句

for语句是许多编程语言用来做循环的常见方法。gawk程序支持C风格的for循环:

for (variable assignment; condition; iteration process)

cat gm5
130 120 135
160 113 140
145 170 215

gawk '</span>{
total = <span class="hljs-number">0</span>
<span class="hljs-keyword">for</span> (i = <span class="hljs-number">1</span>; i < <span class="hljs-number">4</span>; i++)
{
    total += $i

}
avg = total / <span class="hljs-number">3</span>
<span class="hljs-built_in">print</span> <span class="hljs-string">"Average:"</span>,avg
}<span class="hljs-string">' gm5


[root@Jackm Laomeng]# gawk '</span>{
> total = <span class="hljs-number">0</span>
> <span class="hljs-keyword">for</span> (i = <span class="hljs-number">1</span>; i < <span class="hljs-number">4</span>; i++)
> {
>     total += $i
> 
> }
> avg = total / <span class="hljs-number">3</span>
> <span class="hljs-built_in">print</span> <span class="hljs-string">"Average:"</span>,avg
> }<span class="hljs-string">' gm5
Average: 128.333
Average: 137.667
Average: 176.667


5.1 格式化打印


  使用格式化打印命令,称为printf。

  gawk中的printf格式:

  printf "format string",var1,var2...

  format string是格式化输出的关键。它会用文本元素和格式化指定符来具体指定如何呈现

  格式输出。格式化指定符是一种特殊的代码,它会指明什么类型变量可以显示以及如何显示。

  gawk程序会将每个格式化指定符作为命令中列出的每个变量的占符使用。第一个格式化指定

  符会匹配列出的第一个变量,第二个会匹配第二个变量,依次类推.


  格式 :

  %[modifier]control-letter

  其中control-letter是指明显法什么类型的数据值的单字符码,而modifier定义了另一个可

  选择格式化特性。


  控制字母     描述

    c          将一个数作为ASCII字符显示

    d           显示一个整数值

    i           显示一个整数值(跟d一样)

    e           用科学计数法显示一个数

    f           显示一个浮点值

    g           用科学计数法或浮点数中较短的显示

    o           显示一个八进制值

    s           显示一个文本字符串

    x           显示一个十六进制值

    X           显示一个十六进制值,但用大写字母A~F



gawk '</span>BEGIN{
x = <span class="hljs-number">10</span> * <span class="hljs-number">100</span>
printf <span class="hljs-string">"The answer is: %e\n"</span>,x
}<span class="hljs-string">'

gawk '</span>BEGIN{
>     x = <span class="hljs-number">10</span> * <span class="hljs-number">100</span>
>     <span class="hljs-built_in">print</span> <span class="hljs-string">"The answer is: %e\n"</span>,x
>     }<span class="hljs-string">'
The answer is: %e
1000


gawk '</span>BEGIN{
> x = <span class="hljs-number">10</span> * <span class="hljs-number">100</span>
> printf <span class="hljs-string">"The answer is: %e\n"</span>,x
> }<span class="hljs-string">'
The answer is: 1.000000e+03



width: 指定了输出字段最小宽带的数字值。如果输出短于这个值,printf会向右对齐,

并用空格来填充这段空间。如果输出比指定的宽度还要长,它就会覆盖width值。


prec:指定了浮点数中小数点后面位数的数字值,或者文本字符串显示的最大字符数。

-(减号):减号指明在向格式化空间中放入数据时采用左对齐而不是右对齐。


cat data2
Riley Mullen
123 Main Street
Chicago, IL 6061
(312)555-1234


Frank Williams
456 Oak Street
Indianapolis, IN 46201
(317)555-9876

Heley Snell
4231 Elm Street
Detroit, MI 48201
(313)555-4938


gawk '</span>BEGIN{FS=<span class="hljs-string">"\n"</span>; RS=<span class="hljs-string">""</span>} {<span class="hljs-built_in">print</span> $<span class="hljs-number">1</span>,$<span class="hljs-number">4</span>}<span class="hljs-string">' data2
Riley Mullen (312)555-1234
Frank Williams (317)555-9876
Heley Snell (313)555-4938

gawk '</span>BEGIN{FS=<span class="hljs-string">"\n"</span>;RS=<span class="hljs-string">""</span>}{printf <span class="hljs-string">"%s %s\n"</span>,$<span class="hljs-number">1</span>,$<span class="hljs-number">4</span>}<span class="hljs-string">' data2
Riley Mullen (312)555-1234
Frank Williams (317)555-9876
Heley Snell (313)555-4938


cat gm1
data11,data12,data13,data14,data15
data21,data22,data23,data24,data25
data31,data32,data33,data34,data35

gawk '</span>BEGIN{FS=<span class="hljs-string">","</span>}{printf <span class="hljs-string">"%s "</span>,$<span class="hljs-number">1</span>}END{printf <span class="hljs-string">"\n"</span>}<span class="hljs-string">' gm1
data11 data21 data31 


gawk '</span>BEGIN{FS=<span class="hljs-string">"\n"</span>;RS=<span class="hljs-string">""</span>}{printf <span class="hljs-string">"%16s %s\n"</span>,$<span class="hljs-number">1</span>,$<span class="hljs-number">4</span>}<span class="hljs-string">' data2
    Riley Mullen (312)555-1234
  Frank Williams (317)555-9876
     Heley Snell (313)555-4938


gawk '</span>BEGIN{FS=<span class="hljs-string">"\n"</span>; RS=<span class="hljs-string">""</span>}{printf  <span class="hljs-string">"%-16s %s\n"</span>,$<span class="hljs-number">1</span>,$<span class="hljs-number">4</span>}<span class="hljs-string">' data2
Riley Mullen     (312)555-1234
Frank Williams   (317)555-9876
Heley Snell      (313)555-4938

cat gm5
130 120 135
160 113 140
145 170 215

gawk '</span>{
total = <span class="hljs-number">0</span>
<span class="hljs-keyword">for</span> ( i = <span class="hljs-number">1</span>; i < <span class="hljs-number">4</span>; i++)
{
  total += $i
}
avg = total / <span class="hljs-number">3</span>
printf <span class="hljs-string">"Average: %5.1f\n"</span>,avg
}<span class="hljs-string">' gm5


gawk '</span>{
> total = <span class="hljs-number">0</span>
> <span class="hljs-keyword">for</span> ( i = <span class="hljs-number">1</span>; i < <span class="hljs-number">4</span>; i++)
> {
>   total += $i
> }
> avg = total / <span class="hljs-number">3</span>
> printf <span class="hljs-string">"Average: %5.1f\n"</span>,avg
> }<span class="hljs-string">' gm5
Average: 128.3
Average: 137.7
Average: 176.7




6.1 内建函数

6.1.1 数学函数


                         gawk数学函数


   函数               描述


   atan2(x,y)         x/y反正切,x和y以弧度为单位

   cos(x)             x的余弦,x以弧度为单位

   exp(x)             x的指数函数

   init(x)            x的整数部分,取靠近零一侧的值

   log(x)             x的自然对数

   rang()             比0大比1小的随机浮点值

   sin(x)             x的正弦,以x以弧度为单位

   sqrt(x)            x的平方根

   srand(x)           为计算随机数指定一个种子



gawk还支持一些按位操作数据的函数


 and(var1,var2):执行行v1和v2的按位与运算。

 compl(val):执行val的补运算。

 lshift(val,count):将值val左移count位

 or(v1,v2):执行值v1和v2的按位或运算。

 rshift(val,count):将值val右移到count位。

 xor(v1,v2):执行v1和v2的按位异或运算。




 gawk字符串函数


asort(s [,d ])      将数组s按数据元素值排序。索引值会被替换成表示新的排序顺序的连续数字。

                另外如果指定了d,则排序后的数组会在数组d中。

asorti(s( [,d])     将数组s按索引值排序。生成的数组会将索引值作为数据元素值,用连续数字

                    索引来表明排序顺序。另外如果指定了d,排序后的数组会存储在数组d中。


gensub(r,s,h[,t])   查找变量$0或目标字符串t(如果提供了的话)来匹配正则表达式r.如果h是一

                    个以g或G开头的字符串,就用s替换掉匹配文本。如果h是一个数字,它表示要

            替换掉第几处r匹配的地方。


gsub(r,s[,t])       查找变量$0或目标字符串t(如果提供了的话)来匹配正则表达式r.如果找到了,就

                    全部替换成字符串s


index(s,t)          返回字符串t在字符串s中的索引值;如果找到的话返回0


math(s,r[,a])       返回字符s正则表达式r出现位置的索引。如果指定了数组a,它会存储s中匹配正则表达式部分。

split(s,a[,r])      将s用FS字符或正则表达式r(如果指定了的话)分开放到数组a中。返回字段的总数。


sprintf(format, variables)  用提供的format和variables返回一个类似于printf输出的字符串。

sub(r,s[,t])        在变量$0或目标字符串t中查找正则表达式r的匹配。如果找到了,就用字符串s替换掉第一处匹配。


substr(s,i[,n])     返回s中从索引值开始的n个字符组组成的子字符串。如果你未提供n,则返回s剩下的部分。


tolower(s)          将s中的所有字符串转换成小写。

toupper(s)          将s中的所有字符串转换成大写。


gawk '</span>BEGIN{
<span class="hljs-reserved">var</span>[<span class="hljs-string">"a"</span>] = <span class="hljs-number">1</span>
<span class="hljs-reserved">var</span>[<span class="hljs-string">"g"</span>] = <span class="hljs-number">2</span>
<span class="hljs-reserved">var</span>[<span class="hljs-string">"m"</span>] = <span class="hljs-number">3</span>
<span class="hljs-reserved">var</span>[<span class="hljs-string">"u"</span>] = <span class="hljs-number">4</span>
asort(<span class="hljs-reserved">var</span>, test)
<span class="hljs-keyword">for</span> (i <span class="hljs-keyword">in</span> test)
{
    <span class="hljs-built_in">print</span> <span class="hljs-string">"Index:"</span>,i, <span class="hljs-string">"- value:"</span>,test[i]
}
}<span class="hljs-string">'



gawk '</span>BEGIN{
<span class="hljs-reserved">var</span>[<span class="hljs-string">"a"</span>] = <span class="hljs-number">1</span>
> <span class="hljs-reserved">var</span>[<span class="hljs-string">"a"</span>] = <span class="hljs-number">1</span>
> <span class="hljs-reserved">var</span>[<span class="hljs-string">"g"</span>] = <span class="hljs-number">2</span>
> <span class="hljs-reserved">var</span>[<span class="hljs-string">"m"</span>] = <span class="hljs-number">3</span>
> <span class="hljs-reserved">var</span>[<span class="hljs-string">"u"</span>] = <span class="hljs-number">4</span>
> asort(<span class="hljs-reserved">var</span>, test)
> <span class="hljs-keyword">for</span> (i <span class="hljs-keyword">in</span> test)
> {
>     <span class="hljs-built_in">print</span> <span class="hljs-string">"Index:"</span>,i, <span class="hljs-string">"- value:"</span>,test[i]
> }
> }<span class="hljs-string">'
Index: 4 - value: 4
Index: 1 - value: 1
Index: 2 - value: 2
Index: 3 - value: 3

新数组test含有排序后的原数组中的数据元素,但索引值在变为表明正确顺序的数字值了





split函数是将数据字段放到数组中以进一步处理的好办法:


 cat gm1
data11,data12,data13,data14,data15
data21,data22,data23,data24,data25
data31,data32,data33,data34,data35


gawk '</span>BEGIN{FS=<span class="hljs-string">","</span>}{
split($<span class="hljs-number">0</span>,<span class="hljs-reserved">var</span>)
<span class="hljs-built_in">print</span> <span class="hljs-reserved">var</span>[<span class="hljs-number">1</span>],<span class="hljs-reserved">var</span>[<span class="hljs-number">5</span>]
}<span class="hljs-string">' gm1

gawk '</span>BEGIN{FS=<span class="hljs-string">","</span>}{
> split($<span class="hljs-number">0</span>,<span class="hljs-reserved">var</span>)
> <span class="hljs-built_in">print</span> <span class="hljs-reserved">var</span>[<span class="hljs-number">1</span>],<span class="hljs-reserved">var</span>[<span class="hljs-number">5</span>]
> }<span class="hljs-string">' gm1
data11 data15
data21 data25

新数组使用连续数字作为数组索引,从含有第一个数据字段的索引值1开始。



7.  时间函数

mktim(detespec)   将一个按YYYY MM DD HH MM SS [DST]格式指定的日期转换成时间戳值。

strftim(format [,timestamp]) 将当前时间时间戳或timestamp(如果提供了的话)转换成shell函数格式date()的格式化日期。

systime( )        返回当前时间的时间戳。



gawk '</span>BEGIN{
date = systime()
day = strftime(<span class="hljs-string">"%A, %B, %d, %Y, date"</span>)
<span class="hljs-built_in">print</span> day
}<span class="hljs-string">'

gawk '</span>BEGIN{
> date = systime()
> day = strftime(<span class="hljs-string">"%A, %B, %d, %Y, date"</span>)
> <span class="hljs-built_in">print</span> day
> }<span class="hljs-string">'
Tuesday, October, 21, 2014, date

用systime函数来从系统获取当前的epoch时间戳,然后用strftime函数来将它转换成人类可读的格式,

转换过程中使用了shell的date命令的日期格式化字符。




8.自定义函数


8.1.1 定义函数

要定义自己的函数,你必须使用function关键字:

function name([variables])
{
   statements
}


函数名必须能够唯一标识函数。你可以在调用的gawk程序中传给一个或多个变量:

function printthird()
{
   print $3
}

#这个函数会打印数据行中第三个数据字段。

函数还能用return语句返回值:

return value

值可以是变量,或者是最终能计算出值的算式:

function myand(limit)
{
   return int(limit * rand())
}

8.1.2使用自定义变量

  在定义函数时,它必须出现在所有代码之前(包括BEGIN代码块)

cat data2
Riley Mullen
123 Main Street
Chicago, IL 6061
(312)555-1234


Frank Williams
456 Oak Street
Indianapolis, IN 46201
(317)555-9876

Heley Snell
4231 Elm Street
Detroit, MI 48201
(313)555-4938


gawk '</span>
<span class="hljs-reserved">function</span> myprint()
{
     printf <span class="hljs-string">"%-16s - %s\n"</span>,$<span class="hljs-number">1</span>,$<span class="hljs-number">4</span>
}
BEGIN{FS=<span class="hljs-string">"\n"</span>;RS=<span class="hljs-string">""</span>}
{
   myprint()
} <span class="hljs-string">' 

gawk '</span>
> <span class="hljs-reserved">function</span> myprint()
> {
>      printf <span class="hljs-string">"%-16s - %s\n"</span>,$<span class="hljs-number">1</span>,$<span class="hljs-number">4</span>
> }
> BEGIN{FS=<span class="hljs-string">"\n"</span>;RS=<span class="hljs-string">""</span>}
> {
>    myprint()
> } <span class="hljs-string">' 


 gawk '</span>
<span class="hljs-reserved">function</span> myprint()
{
     printf <span class="hljs-string">"%-16s - %s\n"</span>,$<span class="hljs-number">1</span>,$<span class="hljs-number">4</span>
}
BEGIN{FS=<span class="hljs-string">"\n"</span>;RS=<span class="hljs-string">""</span>}
{
   myprint()
} <span class="hljs-string">'  data2
Riley Mullen     - (312)555-1234
Frank Williams   - (317)555-9876
Heley Snell      - (313)555-4938


8.1.3创建库函数

首先,你需要创建一个存储库函数的文件:

 vi funclib

function myprint()
{
  printf "%-16s - %s\n",$1,$2
}
function myrand(limit)
{
  return int(limit * rand())
}
function printthird()
{
   print $3

}

vi laomeng104

BEGIN{FS="\n";RS=""}
{
   myprint()
}

gawk -f funclib -f laomeng104 data2
Riley Mullen     - 123 Main Street
Frank Williams   - 456 Oak Street
Heley Snell      - 4231 Elm Street</span></code></pre> 
 </div> 
</div>
                            </div>
                        </div>
                    </div>
                    <!--PC和WAP自适应版-->
                    <div id="SOHUCS" sid="1722993168984649728"></div>
                    <script type="text/javascript" src="/views/front/js/chanyan.js"></script>
                    <!-- 文章页-底部 动态广告位 -->
                    <div class="youdao-fixed-ad" id="detail_ad_bottom"></div>
                </div>
                <div class="col-md-3">
                    <div class="row" id="ad">
                        <!-- 文章页-右侧1 动态广告位 -->
                        <div id="right-1" class="col-lg-12 col-md-12 col-sm-4 col-xs-4 ad">
                            <div class="youdao-fixed-ad" id="detail_ad_1"> </div>
                        </div>
                        <!-- 文章页-右侧2 动态广告位 -->
                        <div id="right-2" class="col-lg-12 col-md-12 col-sm-4 col-xs-4 ad">
                            <div class="youdao-fixed-ad" id="detail_ad_2"></div>
                        </div>
                        <!-- 文章页-右侧3 动态广告位 -->
                        <div id="right-3" class="col-lg-12 col-md-12 col-sm-4 col-xs-4 ad">
                            <div class="youdao-fixed-ad" id="detail_ad_3"></div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
    <div class="container">
        <h4 class="pt20 mb15 mt0 border-top">你可能感兴趣的:(shell脚本,系统运维,Linux系统命令,sed-gawk)</h4>
        <div id="paradigm-article-related">
            <div class="recommend-post mb30">
                <ul class="widget-links">
                    <li><a href="/article/1835466523163062272.htm"
                           title="Linux sh命令" target="_blank">Linux sh命令</a>
                        <span class="text-muted">fengyehongWorld</span>
<a class="tag" taget="_blank" href="/search/Linux/1.htm">Linux</a><a class="tag" taget="_blank" href="/search/linux/1.htm">linux</a>
                        <div>目录一.基本语法二.选项2.1-c字符串中读取内容,并执行2.1.1基本用法2.1.2获取当前目录下失效的超链接2.2-x每个命令执行之前,将其打印出来2.3结合Here文档使用一.基本语法⏹Linux和Unix系统中用于执行shell脚本或运行命令的命令。sh[选项][脚本文件][参数...]⏹选项-c:从字符串中读取内容,并执行。-x:在每个命令执行之前,将其打印出来。-s:从标准流中读取内容</div>
                    </li>
                    <li><a href="/article/1835391382567612416.htm"
                           title="Shell脚本中sed使用" target="_blank">Shell脚本中sed使用</a>
                        <span class="text-muted">jcrhl321</span>
<a class="tag" taget="_blank" href="/search/linux/1.htm">linux</a>
                        <div>目录一、sed编辑器1、sed概述2、sed的工作流程3、sed命令的常见格式4、sed命令常用操作二、sed常用命令使用1、sed打印2、sed删除3、sed替换4、sed插入与增加4、sed剪切粘贴与复制粘贴一、sed编辑器sed(StreamEDitor)是一个强大而简单的文本解析转换工具,可以读取文本,并根据指定的条件对文本内容进行编辑(删除、替换、添加、移动等),最后输出所有行或者仅输出</div>
                    </li>
                    <li><a href="/article/1835381929642389504.htm"
                           title="shell脚本中sed命令如何使用变量" target="_blank">shell脚本中sed命令如何使用变量</a>
                        <span class="text-muted">歪歪的酒壶</span>
<a class="tag" taget="_blank" href="/search/linux/1.htm">linux</a>
                        <div>在shell脚本中我们常常需要使用sed命令进行配置文件的更新,但是更新的内容又往往根据环境相关。值并不是固定的。这里我们介绍一种在sed命令中使用变量的方法。比如,在nginx的配置中,我们需要根据环境来更新/etc/nginx/sites-available/default中的目录配置。通常我们采用一个变量,来记录当前环境需要配置的目录比如:dist_dir=/home/dev/code/ui</div>
                    </li>
                    <li><a href="/article/1835247244572454912.htm"
                           title="服务器状态监控php源码,服务器状态监控_监控Linux服务器网站状态的SHELL脚本" target="_blank">服务器状态监控php源码,服务器状态监控_监控Linux服务器网站状态的SHELL脚本</a>
                        <span class="text-muted">温糯米</span>
<a class="tag" taget="_blank" href="/search/%E6%9C%8D%E5%8A%A1%E5%99%A8%E7%8A%B6%E6%80%81%E7%9B%91%E6%8E%A7php%E6%BA%90%E7%A0%81/1.htm">服务器状态监控php源码</a>
                        <div>摘要腾兴网为您分享:监控Linux服务器网站状态的SHELL脚本,蜗牛集市,同花顺,探客宝,手柄助手等软件知识,以及日期倒计时插件,云南省教育资源公共,rui手机桌面,小屁孩桌面便签,合金装备崛起复仇,朝夕日历,photoshop图像处理软件,一年级学生每日计划表,悟空找房,饿了吗外卖商家版,逃生,中国民宿网,realpolitiks,交通安全知识竞赛,雅思流利说等软件it资讯,欢迎关注腾兴网。1</div>
                    </li>
                    <li><a href="/article/1835199093819928576.htm"
                           title="docker 安装、运行nginx shell脚本" target="_blank">docker 安装、运行nginx shell脚本</a>
                        <span class="text-muted">三希</span>
<a class="tag" taget="_blank" href="/search/docker/1.htm">docker</a><a class="tag" taget="_blank" href="/search/nginx/1.htm">nginx</a><a class="tag" taget="_blank" href="/search/%E5%AE%B9%E5%99%A8/1.htm">容器</a>
                        <div>以下是一个简单的用于安装和运行DockerNginx的shell脚本:bash#!/bin/bash#安装Docker(如果还未安装)#请根据实际情况调整安装命令#拉取Nginx镜像dockerpullnginx#运行Nginx容器dockerrun-d--namemynginx-p80:80nginx</div>
                    </li>
                    <li><a href="/article/1835187991388188672.htm"
                           title="FastCGI结合docker下的Nginx执行shell脚本" target="_blank">FastCGI结合docker下的Nginx执行shell脚本</a>
                        <span class="text-muted">南波波</span>
<a class="tag" taget="_blank" href="/search/nginx/1.htm">nginx</a><a class="tag" taget="_blank" href="/search/docker/1.htm">docker</a>
                        <div>1使用docker下载Nginx下面展示一些内联代码片。a.#dockerpullnginx#dockerrun--namerunoob-php-nginx-p8088:80-d\-v~/nginx/www:/usr/share/nginx/html:ro\-v~/nginx/conf/conf.d:/etc/nginx/conf.d:ro\nginxb.在~/nginx/conf/conf.d创</div>
                    </li>
                    <li><a href="/article/1835030745471610880.htm"
                           title="【ADB】adb、shell的介绍" target="_blank">【ADB】adb、shell的介绍</a>
                        <span class="text-muted">"啦啦啦"</span>
<a class="tag" taget="_blank" href="/search/adb/1.htm">adb</a><a class="tag" taget="_blank" href="/search/shell/1.htm">shell</a><a class="tag" taget="_blank" href="/search/adb/1.htm">adb</a><a class="tag" taget="_blank" href="/search/shell/1.htm">shell</a>
                        <div>目录adb命令和shell命令的关系adb命令shell命令shell脚本shell脚本运行的环境是什么.sh脚本和.bat脚本有什么区别这两个脚本使用的命令和语法是一样的吗adb命令和shell命令的关系ADB(AndroidDebugBridge)命令和Shell命令都是用于与操作系统交互的命令行工具,但它们的使用环境和目标设备不同。ADB是一种调试工具,主要用于从计算机连接和操作Androi</div>
                    </li>
                    <li><a href="/article/1834983967036633088.htm"
                           title="docker镜像的批量备份和加载" target="_blank">docker镜像的批量备份和加载</a>
                        <span class="text-muted">小卡车555</span>
<a class="tag" taget="_blank" href="/search/docker/1.htm">docker</a>
                        <div>随着微服务的不断发展,docker在微服务的部署中也占着不可缺少的角色,有这样一种场景,需要将服务器上的若干个最新的镜像打成tar.gz做一个备份或者异地部署。针对此问题尝试写了如下shell脚本#vimsaveImages.sh脚本内容如下:#当前需要打包的版本号version=xxx.0.0.1-RELEASE#仓库rep=defaultRep#名称name=defaultNameforiin</div>
                    </li>
                    <li><a href="/article/1834553865958158336.htm"
                           title="CentOS 运维常用的shell脚本" target="_blank">CentOS 运维常用的shell脚本</a>
                        <span class="text-muted">一碗情深</span>
<a class="tag" taget="_blank" href="/search/%E8%BF%90%E7%BB%B4/1.htm">运维</a><a class="tag" taget="_blank" href="/search/%E8%BF%90%E7%BB%B4/1.htm">运维</a><a class="tag" taget="_blank" href="/search/centos/1.htm">centos</a><a class="tag" taget="_blank" href="/search/linux/1.htm">linux</a>
                        <div>文章目录一、操作系统磁盘空间查看实时获取系统运行状态获取cpu、内存等系统运行状态获取系统信息二、应用程序获取进程运行状态查看有多少远程的IP在连接本机三、用户管理统计当前Linux系统中可以登录计算机的账户有多少个创建用户四、自动化管理自动备份日志文件监控的页面地址,对tomcat状态进行重启或维护实时监控本机内存和硬盘,剩余空间不足发送报警邮件一、操作系统磁盘空间查看disk_info.shd</div>
                    </li>
                    <li><a href="/article/1834550458761441280.htm"
                           title="linux脚本监控重启shell脚本,CentOS系统的监控进程状态并自动重启的shell脚本" target="_blank">linux脚本监控重启shell脚本,CentOS系统的监控进程状态并自动重启的shell脚本</a>
                        <span class="text-muted">小雨芝时节</span>

                        <div>在CentOS系统中利用Crontab监控进程是否被结束并自动重启。附加每天凌晨4点自动重启服务器。1、编辑Crontabcrontab-e2、按i进行编辑*/1****/root/monitor.sh#每分钟运行一遍monitor.sh脚本05***/sbin/reboot#每天凌晨5点自动重启服务器12*/1****/root/monitor.sh#每分钟运行一遍monitor.sh脚本05*</div>
                    </li>
                    <li><a href="/article/1834159310054191104.htm"
                           title="shell脚本操作http请求的返回值——shell处理json格式数据" target="_blank">shell脚本操作http请求的返回值——shell处理json格式数据</a>
                        <span class="text-muted">奋起的菜鸟想暴富</span>
<a class="tag" taget="_blank" href="/search/shell/1.htm">shell</a><a class="tag" taget="_blank" href="/search/shell/1.htm">shell</a>
                        <div>日常工作中,我们经常会遇到http请求会返回大量格式固定的数据,而我们只需要其中的一部分,那么怎么提取我们想要的字段呢。这里会介绍一种用shell脚本处理http请求返回,或者处理json格式数据的方式。这里我们用到了jq这个强大的命令行JSON处理器使用.data.list选择JSON数据中的list数组。使用map(select(...))对数组中的每个对象进行筛选,只保留那些element字</div>
                    </li>
                    <li><a href="/article/1834074599403384832.htm"
                           title="Shell脚本综合案例(Linux篇)" target="_blank">Shell脚本综合案例(Linux篇)</a>
                        <span class="text-muted">鸣名旧</span>
<a class="tag" taget="_blank" href="/search/linux/1.htm">linux</a><a class="tag" taget="_blank" href="/search/%E8%BF%90%E7%BB%B4/1.htm">运维</a><a class="tag" taget="_blank" href="/search/%E6%9C%8D%E5%8A%A1%E5%99%A8/1.htm">服务器</a>
                        <div>1.监控目标主机状态监控方法通过ping命令(ICMP协议),如果能ping通,则表示目标主机处于上线状态;反之,则处理下线状态。由于存在网络延迟情况,可能在ping的过程中产生假报警的问题,所以在ping的取值上采用3次报警阈值设置,若3次全部失败,才会报警并产生预警信息。#!/bin/bash#Author:zking#监控目标主机状态​ead-p"请输入目标主机的IP地址:"-t30ipfa</div>
                    </li>
                    <li><a href="/article/1833938727836151808.htm"
                           title="第二十一章 结构化命令case和for,while 循环" target="_blank">第二十一章 结构化命令case和for,while 循环</a>
                        <span class="text-muted">西南蔡徐坤</span>

                        <div>本节所讲内容21,1case-流程控制语句21.2循环循环语句21.3循环语句嵌套21.4实战-3个shell脚本实战21.1流程控制语句控制语句:case变量值in变量或者表达式1)命令序列1;;变量或者表达式1)命令序列2;;.........*)默认命令序列esaccase语句执行流程控制例1编写一个操作文件的脚本#######################################</div>
                    </li>
                    <li><a href="/article/1833746695712763904.htm"
                           title="Windows下的TCP UDP网络调试工具-NetAssist以及Linux下的nc网络调试工具_tcp网络调试工具(1)" target="_blank">Windows下的TCP UDP网络调试工具-NetAssist以及Linux下的nc网络调试工具_tcp网络调试工具(1)</a>
                        <span class="text-muted">2401_83947434</span>
<a class="tag" taget="_blank" href="/search/%E7%A8%8B%E5%BA%8F%E5%91%98/1.htm">程序员</a><a class="tag" taget="_blank" href="/search/%E8%BF%90%E7%BB%B4/1.htm">运维</a><a class="tag" taget="_blank" href="/search/%E5%AD%A6%E4%B9%A0/1.htm">学习</a><a class="tag" taget="_blank" href="/search/%E9%9D%A2%E8%AF%95/1.htm">面试</a>
                        <div>为了做好运维面试路上的助攻手,特整理了上百道【运维技术栈面试题集锦】,让你面试不慌心不跳,高薪offer怀里抱!这次整理的面试题,小到shell、MySQL,大到K8s等云原生技术栈,不仅适合运维新人入行面试需要,还适用于想提升进阶跳槽加薪的运维朋友。本份面试集锦涵盖了174道运维工程师面试题128道k8s面试题108道shell脚本面试题200道Linux面试题51道docker面试题35道Je</div>
                    </li>
                    <li><a href="/article/1833448009745133568.htm"
                           title="【python】最新版小红书js逆向拿到数据,非常详细教程(附完整代码)" target="_blank">【python】最新版小红书js逆向拿到数据,非常详细教程(附完整代码)</a>
                        <span class="text-muted">景天科技苑</span>
<a class="tag" taget="_blank" href="/search/%E7%88%AC%E8%99%AB%E5%89%AF%E4%B8%9A%E5%AE%9E%E6%88%98/1.htm">爬虫副业实战</a><a class="tag" taget="_blank" href="/search/%E9%9B%B6%E5%9F%BA%E7%A1%80/1.htm">零基础</a><a class="tag" taget="_blank" href="/search/%E8%BF%9B%E9%98%B6%E6%95%99%E5%AD%A6/1.htm">进阶教学</a><a class="tag" taget="_blank" href="/search/python/1.htm">python</a><a class="tag" taget="_blank" href="/search/js%E9%80%86%E5%90%91/1.htm">js逆向</a><a class="tag" taget="_blank" href="/search/%E5%B0%8F%E7%BA%A2%E4%B9%A6%E9%80%86%E5%90%91/1.htm">小红书逆向</a><a class="tag" taget="_blank" href="/search/python%E7%88%AC%E8%99%AB/1.htm">python爬虫</a>
                        <div>✨✨欢迎大家来到景天科技苑✨✨养成好习惯,先赞后看哦~作者简介:景天科技苑《头衔》:大厂架构师,华为云开发者社区专家博主,阿里云开发者社区专家博主,CSDN全栈领域优质创作者,掘金优秀博主,51CTO博客专家等。《博客》:Python全栈,前后端开发,人工智能,js逆向,App逆向,网络系统安全,数据分析,Django,fastapi,flask等框架,linux,shell脚本等实操经验,网站搭</div>
                    </li>
                    <li><a href="/article/1833400605431918592.htm"
                           title="shell脚本——正则表达式" target="_blank">shell脚本——正则表达式</a>
                        <span class="text-muted">诚诚k</span>
<a class="tag" taget="_blank" href="/search/%E6%AD%A3%E5%88%99%E8%A1%A8%E8%BE%BE%E5%BC%8F/1.htm">正则表达式</a>
                        <div>概述正则表达式是你所定义的模式模板,Linux工具可以用它来过滤文本。Linux工具(比如sed编辑器或gawk程序)能够在处理数据时使用正则表达式对数据进行模式匹配。如果数据匹配模式,它就会被接受并进一步处理;如果数据不匹配模式,它就会被滤掉。数据流--正则表达式---(1)匹配的数据(2)滤掉的数据正则表达式(或称RegularExpression,简称RE),是用于描述字符排列和匹配模式的一</div>
                    </li>
                    <li><a href="/article/1833381926157774848.htm"
                           title="shell脚本随笔" target="_blank">shell脚本随笔</a>
                        <span class="text-muted">渺小_1912</span>

                        <div>一shell基础1.Shell程序本身的功能是很弱的,比如文件操作、输入输出、进程管理等都得依赖内核。我们运行一个命令,大部分情况下Shell都会去调用内核暴露出来的接口,这就是在使用内核,只是这个过程被Shell隐藏了起来,它自己在背后默默进行,我们看不到而已。2.Shell本身支持的命令并不多,功能也有限,但是Shell可以调用其他的程序。这使得Shell命令的数量可以无限扩展,其结果就是Sh</div>
                    </li>
                    <li><a href="/article/1833255393300672512.htm"
                           title="快速上手基于 BaGet 的脚本自动化构建 .net 应用打包" target="_blank">快速上手基于 BaGet 的脚本自动化构建 .net 应用打包</a>
                        <span class="text-muted">ChaITSimpleLove</span>
<a class="tag" taget="_blank" href="/search/.NET/1.htm">.NET</a><a class="tag" taget="_blank" href="/search/Core/1.htm">Core</a><a class="tag" taget="_blank" href="/search/%E8%B7%A8%E5%B9%B3%E5%8F%B0/1.htm">跨平台</a><a class="tag" taget="_blank" href="/search/%E8%87%AA%E5%8A%A8%E5%8C%96/1.htm">自动化</a><a class="tag" taget="_blank" href="/search/.net/1.htm">.net</a><a class="tag" taget="_blank" href="/search/%E8%BF%90%E7%BB%B4/1.htm">运维</a><a class="tag" taget="_blank" href="/search/BaGet/1.htm">BaGet</a><a class="tag" taget="_blank" href="/search/dotnet/1.htm">dotnet</a><a class="tag" taget="_blank" href="/search/pack/1.htm">pack</a>
                        <div>脚本自动化打包.net应用1.BaGet介绍1.2主要特点1.3使用说明1.3.1安装与部署1.3.1.1Docker部署1.3.1.2手动部署1.3.1.3配置2.应用举例2.1推送包2.2下载包3.配置信息3.1基本配置3.2其他配置选项4.脚本编写4.1编写PowerShell脚本4.2编写Bash脚本4.3运行脚本总结本篇文章我们介绍了如何使用脚本,自动化构建.net应用的nuget包,并</div>
                    </li>
                    <li><a href="/article/1833119073106489344.htm"
                           title="145-Linux权限维持&Rootkit后门&Strace监控&Alias别名&Cron定时任务" target="_blank">145-Linux权限维持&Rootkit后门&Strace监控&Alias别名&Cron定时任务</a>
                        <span class="text-muted">dreamer292</span>
<a class="tag" taget="_blank" href="/search/%23/1.htm">#</a><a class="tag" taget="_blank" href="/search/%E5%B0%8F%E8%BF%AA%E5%AE%89%E5%85%A8%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/1.htm">小迪安全学习笔记</a><a class="tag" taget="_blank" href="/search/%E7%BD%91%E7%BB%9C%E5%AE%89%E5%85%A8/1.htm">网络安全</a><a class="tag" taget="_blank" href="/search/%E5%AE%89%E5%85%A8/1.htm">安全</a><a class="tag" taget="_blank" href="/search/web%E5%AE%89%E5%85%A8/1.htm">web安全</a><a class="tag" taget="_blank" href="/search/%E7%B3%BB%E7%BB%9F%E5%AE%89%E5%85%A8/1.htm">系统安全</a>
                        <div>参考【权限维持】Linux&Rootkit后门&Strace监控&Alias别名&Cron定时任务_aliasls='alerts(){ls$*--color=auto;python-c"-CSDN博客参考FlowUs息流-新一代生产力工具权限维持-Linux-定时任务-Cron后门利用系统的定时任务功能进行反弹Shell1、编辑后门反弹shell脚本vim/etc/.xiaodi.sh内容:#!</div>
                    </li>
                    <li><a href="/article/1833042668821770240.htm"
                           title="linux快速删除大量目录,Linux 快速删除大量小文件方法" target="_blank">linux快速删除大量目录,Linux 快速删除大量小文件方法</a>
                        <span class="text-muted">摸鱼的月鸪</span>
<a class="tag" taget="_blank" href="/search/linux%E5%BF%AB%E9%80%9F%E5%88%A0%E9%99%A4%E5%A4%A7%E9%87%8F%E7%9B%AE%E5%BD%95/1.htm">linux快速删除大量目录</a>
                        <div>当我们在linux系统中要删除数万或者数十万甚至数百万的文件时使用rm-rf*就不太好用,因为要等待很长一段时间。在这种情况之下我们可以使用linux系统命令rsync来巧妙的处理。rsync实际上用的是替换原理,处理数十万个文件也是秒删。1.rsync安装,有些系统默认安装有该命令Ubuntu系统:sudoapt-getinstallrsyncFedora系统:sudoyuminstallrsy</div>
                    </li>
                    <li><a href="/article/1832917741510684672.htm"
                           title="PowerShell 脚本编写 :自动化Windows 开发工作流程" target="_blank">PowerShell 脚本编写 :自动化Windows 开发工作流程</a>
                        <span class="text-muted">小Tomkk</span>
<a class="tag" taget="_blank" href="/search/%E6%95%B0%E6%8D%AE%E5%BA%93/1.htm">数据库</a><a class="tag" taget="_blank" href="/search/%E6%95%B0%E6%8D%AE%E5%BA%93/1.htm">数据库</a><a class="tag" taget="_blank" href="/search/windows/1.htm">windows</a><a class="tag" taget="_blank" href="/search/PowerShell/1.htm">PowerShell</a>
                        <div>PowerShell脚本编写:自动化Windows开发工作流程在现代开发工作中,自动化已成为提高生产力的关键部分。对于Windows用户,PowerShell是一种强大的自动化工具,它能够帮助开发者简化和自动化日常任务。本文将介绍如何使用PowerShell脚本来实现自动化Windows开发工作流程,包括每天清理磁盘、自动备份MySQL数据库等。文章目录PowerShell脚本编写:自动化Wind</div>
                    </li>
                    <li><a href="/article/1832899203307761664.htm"
                           title="Build step ‘Execute shell‘ marked build as failure" target="_blank">Build step ‘Execute shell‘ marked build as failure</a>
                        <span class="text-muted">玉梅小洋</span>
<a class="tag" taget="_blank" href="/search/FAQ/1.htm">FAQ</a><a class="tag" taget="_blank" href="/search/jenkins/1.htm">jenkins</a>
                        <div>问题现象Jenkins构建时运行脚本报错时:Buildstep'Executeshell'markedbuildasfailureFinished:FAILURE解决方法1.磁盘空间不足导致报错。2.请在执行的shell脚本中第一行加#!/bin/bash#!/bin/bash......注意#!/bin/bash只能放在第一行3.如果2还是不行,那么将#!/bin/bash替换为#!/usr/b</div>
                    </li>
                    <li><a href="/article/1832747296635318272.htm"
                           title="Shell脚本函数与数组(Linux篇)" target="_blank">Shell脚本函数与数组(Linux篇)</a>
                        <span class="text-muted">鸣名旧</span>
<a class="tag" taget="_blank" href="/search/chrome/1.htm">chrome</a><a class="tag" taget="_blank" href="/search/linux/1.htm">linux</a><a class="tag" taget="_blank" href="/search/%E5%89%8D%E7%AB%AF/1.htm">前端</a>
                        <div>1.函数1.1.函数定义linuxshell可以用户定义函数,然后在shell脚本中可以随便调用。Shell函数定义的语法格式如下:[function]funname[()]{ 函数体 [returnint;]}function关键字可写,也可不写。格式1:简化写法,不写function关键字、函数名(){ 函数体}格式2:标准写法,推荐使用function函数名(){命令序列}所有函数在使用前必</div>
                    </li>
                    <li><a href="/article/1832737972169043968.htm"
                           title="Shell脚本基本语法(Linux篇)" target="_blank">Shell脚本基本语法(Linux篇)</a>
                        <span class="text-muted">鸣名旧</span>
<a class="tag" taget="_blank" href="/search/linux/1.htm">linux</a><a class="tag" taget="_blank" href="/search/%E6%9C%8D%E5%8A%A1%E5%99%A8/1.htm">服务器</a><a class="tag" taget="_blank" href="/search/%E8%BF%90%E7%BB%B4/1.htm">运维</a>
                        <div>1.变量定义变量命名规则:可以包含字母,数字,下划线,首字母不能用数字开头,中间不能又空格;为变量赋值等号之间不能为空格;变量命名不能使用标点符号,不能使用bash的关键字;shell中默认的变量的类型都是字符,就算是数字字符也会被认为是字符串,如果需要进行字符相加,则必须指定变量为数值;如果定义的变量中没有空格,则定义变量时可以使用单引号或双引号,也可以使用,如:name=zs,如果变量中包含了</div>
                    </li>
                    <li><a href="/article/1832708217466089472.htm"
                           title="《java代码记录》-使用java运行服务器上的.sh文件" target="_blank">《java代码记录》-使用java运行服务器上的.sh文件</a>
                        <span class="text-muted">一单成</span>
<a class="tag" taget="_blank" href="/search/%E5%BC%80%E5%8F%91%E4%BD%BF%E7%94%A8%E5%B7%A5%E5%85%B7%E7%B1%BB/1.htm">开发使用工具类</a><a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/%E6%9C%8D%E5%8A%A1%E5%99%A8/1.htm">服务器</a><a class="tag" taget="_blank" href="/search/%E5%BC%80%E5%8F%91%E8%AF%AD%E8%A8%80/1.htm">开发语言</a>
                        <div>阿丹:记录一下使用java来运行服务器上的sh脚本。importjava.io.IOException;publicclassRunShellScript{publicstaticvoidmain(String[]args){StringscriptPath="/path/to/your/script.sh";//替换为你的Shell脚本路径try{//使用Runtime.exec方法执行Shel</div>
                    </li>
                    <li><a href="/article/1832705570013016064.htm"
                           title="Oracle Linux 8.10 ARM 一键安装 Oracle 19C 单机" target="_blank">Oracle Linux 8.10 ARM 一键安装 Oracle 19C 单机</a>
                        <span class="text-muted">TanxiaoLee</span>
<a class="tag" taget="_blank" href="/search/oracle/1.htm">oracle</a><a class="tag" taget="_blank" href="/search/linux/1.htm">linux</a><a class="tag" taget="_blank" href="/search/arm%E5%BC%80%E5%8F%91/1.htm">arm开发</a><a class="tag" taget="_blank" href="/search/%E6%95%B0%E6%8D%AE%E5%BA%93/1.htm">数据库</a><a class="tag" taget="_blank" href="/search/%E8%BF%90%E7%BB%B4/1.htm">运维</a>
                        <div>前言Oracle一键安装脚本,演示OracleLinux8.10ARM一键安装Oracle19C单机(全程无需人工干预)。⭐️脚本下载地址:Shell脚本安装Oracle数据库前置准备1、系统组安装好操作系统(支持最小化安装)2、网络组配置好主机网络,通常只需要一个公网IP地址3、DBA创建软件目录:mkdir/soft4、DBA上传Oracle安装介质(基础包,补丁包)到/soft目录下5、DB</div>
                    </li>
                    <li><a href="/article/1832521752278822912.htm"
                           title="Linux shell脚本实现命令批处理和文件批量分发" target="_blank">Linux shell脚本实现命令批处理和文件批量分发</a>
                        <span class="text-muted">2401_85191843</span>
<a class="tag" taget="_blank" href="/search/linux/1.htm">linux</a><a class="tag" taget="_blank" href="/search/%E8%BF%90%E7%BB%B4/1.htm">运维</a><a class="tag" taget="_blank" href="/search/%E6%9C%8D%E5%8A%A1%E5%99%A8/1.htm">服务器</a>
                        <div>使用$*接收脚本所有参数for循环遍历hosts文件中的ip地址通过ssh$host$cmd实现目的ip命令eval命令判断并打印命令执行结果for循环遍历完hosts则脚本运行结束3、批量分发脚本原理$1和$2接收参数文件名和分发路径for循环遍历hosts文件中的ip地址通过scp$1$host:$2实现分发文件到目的主机eval命令判断并打印命令执行结果for循环遍历完hosts则脚本运行结</div>
                    </li>
                    <li><a href="/article/1832520492918075392.htm"
                           title="2024年最新2024整理 iptables防火墙学习笔记大全_modepro iptables(1),2024年最新含BATJM大厂" target="_blank">2024年最新2024整理 iptables防火墙学习笔记大全_modepro iptables(1),2024年最新含BATJM大厂</a>
                        <span class="text-muted">2024spring</span>
<a class="tag" taget="_blank" href="/search/%E7%A8%8B%E5%BA%8F%E5%91%98/1.htm">程序员</a><a class="tag" taget="_blank" href="/search/%E5%AD%A6%E4%B9%A0/1.htm">学习</a><a class="tag" taget="_blank" href="/search/%E7%AC%94%E8%AE%B0/1.htm">笔记</a>
                        <div>为了做好运维面试路上的助攻手,特整理了上百道【运维技术栈面试题集锦】,让你面试不慌心不跳,高薪offer怀里抱!这次整理的面试题,小到shell、MySQL,大到K8s等云原生技术栈,不仅适合运维新人入行面试需要,还适用于想提升进阶跳槽加薪的运维朋友。本份面试集锦涵盖了174道运维工程师面试题128道k8s面试题108道shell脚本面试题200道Linux面试题51道docker面试题35道Je</div>
                    </li>
                    <li><a href="/article/1832453178252161024.htm"
                           title="Shell脚本字符串处理(Linux篇)" target="_blank">Shell脚本字符串处理(Linux篇)</a>
                        <span class="text-muted">鸣名旧</span>
<a class="tag" taget="_blank" href="/search/linux/1.htm">linux</a><a class="tag" taget="_blank" href="/search/postgresql/1.htm">postgresql</a><a class="tag" taget="_blank" href="/search/%E8%BF%90%E7%BB%B4/1.htm">运维</a>
                        <div>1.字符串处理1.1.cutcut命令从文件的每一行剪切字节、字符和字段并将这些字节、字符和字段写至标准输出。语法格式如下:命令格式:cut[选项]文件名选项参数说明:选项说明-b选中第几个字符-c选中多少个字符-d按照指定分割符进行分割,默认的分割符是制表符,注意分割符不能使用空格。-f提取第几列示例一:初识cut命令#打印b字符:root@zking:~#echo"acbdef"|cut-b2</div>
                    </li>
                    <li><a href="/article/1832019135245152256.htm"
                           title="Redis 持久化存储shell脚本" target="_blank">Redis 持久化存储shell脚本</a>
                        <span class="text-muted">Ballad999</span>
<a class="tag" taget="_blank" href="/search/redis/1.htm">redis</a><a class="tag" taget="_blank" href="/search/%E7%BC%93%E5%AD%98/1.htm">缓存</a><a class="tag" taget="_blank" href="/search/%E6%95%B0%E6%8D%AE%E5%BA%93/1.htm">数据库</a>
                        <div>#!/bin/bash#安装Redis相关依赖yuminstall-ygccmakewget#下载Redis源码wgethttp://download.redis.io/releases/redis-6.2.5.tar.gz#解压源码包tarxzfredis-6.2.5.tar.gzcdredis-6.2.5#编译并安装Redismakesudomakeinstall#检查Redis是否安装成功i</div>
                    </li>
                                <li><a href="/article/80.htm"
                                       title="java杨辉三角" target="_blank">java杨辉三角</a>
                                    <span class="text-muted">3213213333332132</span>
<a class="tag" taget="_blank" href="/search/java%E5%9F%BA%E7%A1%80/1.htm">java基础</a>
                                    <div>
package com.algorithm;

/**
 * @Description 杨辉三角
 * @author FuJianyong
 * 2015-1-22上午10:10:59
 */
public class YangHui {
	public static void main(String[] args) {
		//初始化二维数组长度
		int[][] y</div>
                                </li>
                                <li><a href="/article/207.htm"
                                       title="《大话重构》之大布局的辛酸历史" target="_blank">《大话重构》之大布局的辛酸历史</a>
                                    <span class="text-muted">白糖_</span>
<a class="tag" taget="_blank" href="/search/%E9%87%8D%E6%9E%84/1.htm">重构</a>
                                    <div>《大话重构》中提到“大布局你伤不起”,如果企图重构一个陈旧的大型系统是有非常大的风险,重构不是想象中那么简单。我目前所在公司正好对产品做了一次“大布局重构”,下面我就分享这个“大布局”项目经验给大家。 
  
 
 背景 
 
        公司专注于企业级管理产品软件,企业有大中小之分,在2000年初公司用JSP/Servlet开发了一套针对中</div>
                                </li>
                                <li><a href="/article/334.htm"
                                       title="电驴链接在线视频播放源码" target="_blank">电驴链接在线视频播放源码</a>
                                    <span class="text-muted">dubinwei</span>
<a class="tag" taget="_blank" href="/search/%E6%BA%90%E7%A0%81/1.htm">源码</a><a class="tag" taget="_blank" href="/search/%E7%94%B5%E9%A9%B4/1.htm">电驴</a><a class="tag" taget="_blank" href="/search/%E6%92%AD%E6%94%BE%E5%99%A8/1.htm">播放器</a><a class="tag" taget="_blank" href="/search/%E8%A7%86%E9%A2%91/1.htm">视频</a><a class="tag" taget="_blank" href="/search/ed2k/1.htm">ed2k</a>
                                    <div>本项目是个搜索电驴(ed2k)链接的应用,借助于磁力视频播放器(官网: 
http://loveandroid.duapp.com/ 开放平台),可以实现在线播放视频,也可以用迅雷或者其他下载工具下载。 
项目源码: 
http://git.oschina.net/svo/Emule,动态更新。也可从附件中下载。 
项目源码依赖于两个库项目,库项目一链接: 
http://git.oschina.</div>
                                </li>
                                <li><a href="/article/461.htm"
                                       title="Javascript中函数的toString()方法" target="_blank">Javascript中函数的toString()方法</a>
                                    <span class="text-muted">周凡杨</span>
<a class="tag" taget="_blank" href="/search/JavaScript/1.htm">JavaScript</a><a class="tag" taget="_blank" href="/search/js/1.htm">js</a><a class="tag" taget="_blank" href="/search/toString/1.htm">toString</a><a class="tag" taget="_blank" href="/search/function/1.htm">function</a><a class="tag" taget="_blank" href="/search/object/1.htm">object</a>
                                    <div>简述 
    The toString() method returns a string representing the source code of the function. 
    简译之,Javascript的toString()方法返回一个代表函数源代码的字符串。 
句法 
    function.</div>
                                </li>
                                <li><a href="/article/588.htm"
                                       title="struts处理自定义异常" target="_blank">struts处理自定义异常</a>
                                    <span class="text-muted">g21121</span>
<a class="tag" taget="_blank" href="/search/struts/1.htm">struts</a>
                                    <div>很多时候我们会用到自定义异常来表示特定的错误情况,自定义异常比较简单,只要分清是运行时异常还是非运行时异常即可,运行时异常不需要捕获,继承自RuntimeException,是由容器自己抛出,例如空指针异常。 
非运行时异常继承自Exception,在抛出后需要捕获,例如文件未找到异常。 
此处我们用的是非运行时异常,首先定义一个异常LoginException: 
/**
 * 类描述:登录相</div>
                                </li>
                                <li><a href="/article/715.htm"
                                       title="Linux中find常见用法示例" target="_blank">Linux中find常见用法示例</a>
                                    <span class="text-muted">510888780</span>
<a class="tag" taget="_blank" href="/search/linux/1.htm">linux</a>
                                    <div>Linux中find常见用法示例 
 
·find   path   -option   [   -print ]   [ -exec   -ok   command ]   {} \; 
 
 
 
 
find命令的参数;</div>
                                </li>
                                <li><a href="/article/842.htm"
                                       title="SpringMVC的各种参数绑定方式" target="_blank">SpringMVC的各种参数绑定方式</a>
                                    <span class="text-muted">Harry642</span>
<a class="tag" taget="_blank" href="/search/springMVC/1.htm">springMVC</a><a class="tag" taget="_blank" href="/search/%E7%BB%91%E5%AE%9A/1.htm">绑定</a><a class="tag" taget="_blank" href="/search/%E8%A1%A8%E5%8D%95/1.htm">表单</a>
                                    <div>1. 基本数据类型(以int为例,其他类似): 
Controller代码: 
 

    @RequestMapping("saysth.do")
    public void test(int count) {
    }
 
表单代码: 
 

<form action="saysth.do" method="post&q</div>
                                </li>
                                <li><a href="/article/969.htm"
                                       title="Java 获取Oracle ROWID" target="_blank">Java 获取Oracle ROWID</a>
                                    <span class="text-muted">aijuans</span>
<a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/oracle/1.htm">oracle</a>
                                    <div>  
A ROWID is an identification tag unique for each row of an Oracle Database table. The ROWID can be thought of as a virtual column, containing the ID for each row. 
The oracle.sql.ROWID class i</div>
                                </li>
                                <li><a href="/article/1096.htm"
                                       title="java获取方法的参数名" target="_blank">java获取方法的参数名</a>
                                    <span class="text-muted">antlove</span>
<a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/jdk/1.htm">jdk</a><a class="tag" taget="_blank" href="/search/parameter/1.htm">parameter</a><a class="tag" taget="_blank" href="/search/method/1.htm">method</a><a class="tag" taget="_blank" href="/search/reflect/1.htm">reflect</a>
                                    <div>reflect.ClassInformationUtil.java 
package reflect;

import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtMethod;
import javassist.Modifier;
import javassist.bytecode.CodeAtt</div>
                                </li>
                                <li><a href="/article/1223.htm"
                                       title="JAVA正则表达式匹配 查找 替换 提取操作" target="_blank">JAVA正则表达式匹配 查找 替换 提取操作</a>
                                    <span class="text-muted">百合不是茶</span>
<a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/%E6%AD%A3%E5%88%99%E8%A1%A8%E8%BE%BE%E5%BC%8F/1.htm">正则表达式</a><a class="tag" taget="_blank" href="/search/%E6%9B%BF%E6%8D%A2/1.htm">替换</a><a class="tag" taget="_blank" href="/search/%E6%8F%90%E5%8F%96/1.htm">提取</a><a class="tag" taget="_blank" href="/search/%E6%9F%A5%E6%89%BE/1.htm">查找</a>
                                    <div>正则表达式的查找;主要是用到String类中的split(); 
      String str; 
     str.split();方法中传入按照什么规则截取,返回一个String数组 
  
常见的截取规则: 
str.split("\\.")按照.来截取

str.</div>
                                </li>
                                <li><a href="/article/1350.htm"
                                       title="Java中equals()与hashCode()方法详解" target="_blank">Java中equals()与hashCode()方法详解</a>
                                    <span class="text-muted">bijian1013</span>
<a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/set/1.htm">set</a><a class="tag" taget="_blank" href="/search/equals%28%29/1.htm">equals()</a><a class="tag" taget="_blank" href="/search/hashCode%28%29/1.htm">hashCode()</a>
                                    <div>一.equals()方法详解 
    equals()方法在object类中定义如下:  
public boolean equals(Object obj) {
    return (this == obj);
}
 
   很明显是对两个对象的地址值进行的比较(即比较引用是否相同)。但是我们知道,String 、Math、I</div>
                                </li>
                                <li><a href="/article/1477.htm"
                                       title="精通Oracle10编程SQL(4)使用SQL语句" target="_blank">精通Oracle10编程SQL(4)使用SQL语句</a>
                                    <span class="text-muted">bijian1013</span>
<a class="tag" taget="_blank" href="/search/oracle/1.htm">oracle</a><a class="tag" taget="_blank" href="/search/%E6%95%B0%E6%8D%AE%E5%BA%93/1.htm">数据库</a><a class="tag" taget="_blank" href="/search/plsql/1.htm">plsql</a>
                                    <div>--工资级别表
create table SALGRADE
(
  GRADE    NUMBER(10),
  LOSAL    NUMBER(10,2),
  HISAL    NUMBER(10,2)
)

insert into SALGRADE values(1,0,100);
insert into SALGRADE values(2,100,200);
inser</div>
                                </li>
                                <li><a href="/article/1604.htm"
                                       title="【Nginx二】Nginx作为静态文件HTTP服务器" target="_blank">【Nginx二】Nginx作为静态文件HTTP服务器</a>
                                    <span class="text-muted">bit1129</span>
<a class="tag" taget="_blank" href="/search/HTTP%E6%9C%8D%E5%8A%A1%E5%99%A8/1.htm">HTTP服务器</a>
                                    <div> Nginx作为静态文件HTTP服务器 
 
  在本地系统中创建/data/www目录,存放html文件(包括index.html) 
 创建/data/images目录,存放imags图片 
 在主配置文件中添加http指令 
 
  
http {
    server {
        listen       80;
        server_name  </div>
                                </li>
                                <li><a href="/article/1731.htm"
                                       title="kafka获得最新partition offset" target="_blank">kafka获得最新partition offset</a>
                                    <span class="text-muted">blackproof</span>
<a class="tag" taget="_blank" href="/search/kafka/1.htm">kafka</a><a class="tag" taget="_blank" href="/search/partition/1.htm">partition</a><a class="tag" taget="_blank" href="/search/offset/1.htm">offset</a><a class="tag" taget="_blank" href="/search/%E6%9C%80%E6%96%B0/1.htm">最新</a>
                                    <div>kafka获得partition下标,需要用到kafka的simpleconsumer 
  
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.</div>
                                </li>
                                <li><a href="/article/1858.htm"
                                       title="centos 7安装docker两种方式" target="_blank">centos 7安装docker两种方式</a>
                                    <span class="text-muted">ronin47</span>

                                    <div>      第一种是采用yum 方式 
             yum install -y docker 
          </div>
                                </li>
                                <li><a href="/article/1985.htm"
                                       title="java-60-在O(1)时间删除链表结点" target="_blank">java-60-在O(1)时间删除链表结点</a>
                                    <span class="text-muted">bylijinnan</span>
<a class="tag" taget="_blank" href="/search/java/1.htm">java</a>
                                    <div>

public class DeleteNode_O1_Time {

	/**
	 * Q 60 在O(1)时间删除链表结点
	 * 给定链表的头指针和一个结点指针(!!),在O(1)时间删除该结点
	 * 
	 * Assume the list is:
	 * head->...->nodeToDelete->mNode->nNode->..</div>
                                </li>
                                <li><a href="/article/2112.htm"
                                       title="nginx利用proxy_cache来缓存文件" target="_blank">nginx利用proxy_cache来缓存文件</a>
                                    <span class="text-muted">cfyme</span>
<a class="tag" taget="_blank" href="/search/cache/1.htm">cache</a>
                                    <div>user  zhangy users;
worker_processes 10;
error_log  /var/vlogs/nginx_error.log  crit;
pid        /var/vlogs/nginx.pid;
#Specifies the value for ma</div>
                                </li>
                                <li><a href="/article/2239.htm"
                                       title="[JWFD开源工作流]JWFD嵌入式语法分析器负号的使用问题" target="_blank">[JWFD开源工作流]JWFD嵌入式语法分析器负号的使用问题</a>
                                    <span class="text-muted">comsci</span>
<a class="tag" taget="_blank" href="/search/%E5%B5%8C%E5%85%A5%E5%BC%8F/1.htm">嵌入式</a>
                                    <div> 
    假如我们需要用JWFD的语法分析模块定义一个带负号的方程式,直接在方程式之前添加负号是不正确的,而必须这样做: 
 
    string str01 = "a=3.14;b=2.71;c=0;c-((a*a)+(b*b))" 
 
    定义一个0整数c,然后用这个整数c去</div>
                                </li>
                                <li><a href="/article/2366.htm"
                                       title="如何集成支付宝官方文档" target="_blank">如何集成支付宝官方文档</a>
                                    <span class="text-muted">dai_lm</span>
<a class="tag" taget="_blank" href="/search/android/1.htm">android</a>
                                    <div>官方文档下载地址 
 
https://b.alipay.com/order/productDetail.htm?productId=2012120700377310&tabId=4#ps-tabinfo-hash 
 
集成的必要条件 
1. 需要有自己的Server接收支付宝的消息 
2. 需要先制作app,然后提交支付宝审核,通过后才能集成 
 
调试的时候估计会真的扣款,请注意 
</div>
                                </li>
                                <li><a href="/article/2493.htm"
                                       title="应该在什么时候使用Hadoop" target="_blank">应该在什么时候使用Hadoop</a>
                                    <span class="text-muted">datamachine</span>
<a class="tag" taget="_blank" href="/search/hadoop/1.htm">hadoop</a>
                                    <div>原帖地址:http://blog.chinaunix.net/uid-301743-id-3925358.html 
 
存档,某些观点与我不谋而合,过度技术化不可取,且hadoop并非万能。 
 
--------------------------------------------万能的分割线-------------------------------- 
有人问我,“你在大数据和Hado</div>
                                </li>
                                <li><a href="/article/2620.htm"
                                       title="在GridView中对于有外键的字段使用关联模型进行搜索和排序" target="_blank">在GridView中对于有外键的字段使用关联模型进行搜索和排序</a>
                                    <span class="text-muted">dcj3sjt126com</span>
<a class="tag" taget="_blank" href="/search/yii/1.htm">yii</a>
                                    <div>在GridView中使用关联模型进行搜索和排序 
首先我们有两个模型它们直接有关联:   
class Author extends CActiveRecord {
...
}
 
class Post extends CActiveRecord {
...
    function relations() {
        return array(
            '</div>
                                </li>
                                <li><a href="/article/2747.htm"
                                       title="使用NSString 的格式化大全" target="_blank">使用NSString 的格式化大全</a>
                                    <span class="text-muted">dcj3sjt126com</span>
<a class="tag" taget="_blank" href="/search/Objective-C/1.htm">Objective-C</a>
                                    <div>格式定义The format specifiers supported by the NSString formatting methods and CFString formatting functions follow the IEEE printf specification; the specifiers are summarized in Table 1. Note that you c</div>
                                </li>
                                <li><a href="/article/2874.htm"
                                       title="使用activeX插件对象object滚动有重影" target="_blank">使用activeX插件对象object滚动有重影</a>
                                    <span class="text-muted">蕃薯耀</span>
<a class="tag" taget="_blank" href="/search/activeX%E6%8F%92%E4%BB%B6/1.htm">activeX插件</a><a class="tag" taget="_blank" href="/search/%E6%BB%9A%E5%8A%A8%E6%9C%89%E9%87%8D%E5%BD%B1/1.htm">滚动有重影</a>
                                    <div>    
使用activeX插件对象object滚动有重影       <object style="width:0;" id="abc" classid="CLSID:D3E3970F-2927-9680-BBB4-5D0889909DF6" codebase="activex/OAX339.CAB#</div>
                                </li>
                                <li><a href="/article/3001.htm"
                                       title="SpringMVC4零配置" target="_blank">SpringMVC4零配置</a>
                                    <span class="text-muted">hanqunfeng</span>
<a class="tag" taget="_blank" href="/search/springmvc4/1.htm">springmvc4</a>
                                    <div>基于Servlet3.0规范和SpringMVC4注解式配置方式,实现零xml配置,弄了个小demo,供交流讨论。 
  
  
项目说明如下: 
1.db.sql是项目中用到的表,数据库使用的是oracle11g 
2.该项目使用mvn进行管理,私服为自搭建nexus,项目只用到一个第三方 jar,就是oracle的驱动; 
3.默认项目为零配置启动,如果需要更改启动方式,请</div>
                                </li>
                                <li><a href="/article/3128.htm"
                                       title="《开源框架那点事儿16》:缓存相关代码的演变" target="_blank">《开源框架那点事儿16》:缓存相关代码的演变</a>
                                    <span class="text-muted">j2eetop</span>
<a class="tag" taget="_blank" href="/search/%E5%BC%80%E6%BA%90%E6%A1%86%E6%9E%B6/1.htm">开源框架</a>
                                    <div>问题引入 
上次我参与某个大型项目的优化工作,由于系统要求有比较高的TPS,因此就免不了要使用缓冲。 
该项目中用的缓冲比较多,有MemCache,有Redis,有的还需要提供二级缓冲,也就是说应用服务器这层也可以设置一些缓冲。 
当然去看相关实现代代码的时候,大致是下面的样子。    
[java] 
view plain 
copy 
print 
?   
 
 public vo</div>
                                </li>
                                <li><a href="/article/3255.htm"
                                       title="AngularJS浅析" target="_blank">AngularJS浅析</a>
                                    <span class="text-muted">kvhur</span>
<a class="tag" taget="_blank" href="/search/JavaScript/1.htm">JavaScript</a>
                                    <div>概念 
 
 AngularJS is a structural framework for dynamic web apps. 
 了解更多详情请见原文链接:http://www.gbtags.com/gb/share/5726.htm 
 Directive 
扩展html,给html添加声明语句,以便实现自己的需求。对于页面中html元素以ng为前缀的属性名称,ng是angular的命名空间</div>
                                </li>
                                <li><a href="/article/3382.htm"
                                       title="架构师之jdk的bug排查(一)---------------split的点号陷阱" target="_blank">架构师之jdk的bug排查(一)---------------split的点号陷阱</a>
                                    <span class="text-muted">nannan408</span>
<a class="tag" taget="_blank" href="/search/split/1.htm">split</a>
                                    <div>1.前言. 
   jdk1.6的lang包的split方法是有bug的,它不能有效识别A.b.c这种类型,导致截取长度始终是0.而对于其他字符,则无此问题.不知道官方有没有修复这个bug. 
2.代码 
 

String[] paths = "object.object2.prop11".split("'");
System.ou</div>
                                </li>
                                <li><a href="/article/3509.htm"
                                       title="如何对10亿数据量级的mongoDB作高效的全表扫描" target="_blank">如何对10亿数据量级的mongoDB作高效的全表扫描</a>
                                    <span class="text-muted">quentinXXZ</span>
<a class="tag" taget="_blank" href="/search/mongodb/1.htm">mongodb</a>
                                    <div>  本文链接: 
http://quentinXXZ.iteye.com/blog/2149440  
一、正常情况下,不应该有这种需求 
首先,大家应该有个概念,标题中的这个问题,在大多情况下是一个伪命题,不应该被提出来。要知道,对于一般较大数据量的数据库,全表查询,这种操作一般情况下是不应该出现的,在做正常查询的时候,如果是范围查询,你至少应该要加上limit。 
说一下,</div>
                                </li>
                                <li><a href="/article/3636.htm"
                                       title="C语言算法之水仙花数" target="_blank">C语言算法之水仙花数</a>
                                    <span class="text-muted">qiufeihu</span>
<a class="tag" taget="_blank" href="/search/c/1.htm">c</a><a class="tag" taget="_blank" href="/search/%E7%AE%97%E6%B3%95/1.htm">算法</a>
                                    <div>/**
* 水仙花数
*/
#include <stdio.h>
#define N 10
int main()
{
    int x,y,z;
    for(x=1;x<=N;x++)
    	for(y=0;y<=N;y++)
    		for(z=0;z<=N;z++)
    			if(x*100+y*10+z == x*x*x</div>
                                </li>
                                <li><a href="/article/3763.htm"
                                       title="JSP指令" target="_blank">JSP指令</a>
                                    <span class="text-muted">wyzuomumu</span>
<a class="tag" taget="_blank" href="/search/jsp/1.htm">jsp</a>
                                    <div> 
 jsp指令的一般语法格式: <%@ 指令名 属性 =”值 ” %> 
  常用的三种指令: page,include,taglib 
 page指令语法形式: <%@ page 属性 1=”值 1” 属性 2=”值 2”%> 
 include指令语法形式: <%@include file=”relative url”%> (jsp可以通过 include</div>
                                </li>
                </ul>
            </div>
        </div>
    </div>

<div>
    <div class="container">
        <div class="indexes">
            <strong>按字母分类:</strong>
            <a href="/tags/A/1.htm" target="_blank">A</a><a href="/tags/B/1.htm" target="_blank">B</a><a href="/tags/C/1.htm" target="_blank">C</a><a
                href="/tags/D/1.htm" target="_blank">D</a><a href="/tags/E/1.htm" target="_blank">E</a><a href="/tags/F/1.htm" target="_blank">F</a><a
                href="/tags/G/1.htm" target="_blank">G</a><a href="/tags/H/1.htm" target="_blank">H</a><a href="/tags/I/1.htm" target="_blank">I</a><a
                href="/tags/J/1.htm" target="_blank">J</a><a href="/tags/K/1.htm" target="_blank">K</a><a href="/tags/L/1.htm" target="_blank">L</a><a
                href="/tags/M/1.htm" target="_blank">M</a><a href="/tags/N/1.htm" target="_blank">N</a><a href="/tags/O/1.htm" target="_blank">O</a><a
                href="/tags/P/1.htm" target="_blank">P</a><a href="/tags/Q/1.htm" target="_blank">Q</a><a href="/tags/R/1.htm" target="_blank">R</a><a
                href="/tags/S/1.htm" target="_blank">S</a><a href="/tags/T/1.htm" target="_blank">T</a><a href="/tags/U/1.htm" target="_blank">U</a><a
                href="/tags/V/1.htm" target="_blank">V</a><a href="/tags/W/1.htm" target="_blank">W</a><a href="/tags/X/1.htm" target="_blank">X</a><a
                href="/tags/Y/1.htm" target="_blank">Y</a><a href="/tags/Z/1.htm" target="_blank">Z</a><a href="/tags/0/1.htm" target="_blank">其他</a>
        </div>
    </div>
</div>
<footer id="footer" class="mb30 mt30">
    <div class="container">
        <div class="footBglm">
            <a target="_blank" href="/">首页</a> -
            <a target="_blank" href="/custom/about.htm">关于我们</a> -
            <a target="_blank" href="/search/Java/1.htm">站内搜索</a> -
            <a target="_blank" href="/sitemap.txt">Sitemap</a> -
            <a target="_blank" href="/custom/delete.htm">侵权投诉</a>
        </div>
        <div class="copyright">版权所有 IT知识库 CopyRight © 2000-2050 E-COM-NET.COM , All Rights Reserved.
<!--            <a href="https://beian.miit.gov.cn/" rel="nofollow" target="_blank">京ICP备09083238号</a><br>-->
        </div>
    </div>
</footer>
<!-- 代码高亮 -->
<script type="text/javascript" src="/static/syntaxhighlighter/scripts/shCore.js"></script>
<script type="text/javascript" src="/static/syntaxhighlighter/scripts/shLegacy.js"></script>
<script type="text/javascript" src="/static/syntaxhighlighter/scripts/shAutoloader.js"></script>
<link type="text/css" rel="stylesheet" href="/static/syntaxhighlighter/styles/shCoreDefault.css"/>
<script type="text/javascript" src="/static/syntaxhighlighter/src/my_start_1.js"></script>





</body>

</html><script data-cfasync="false" src="/cdn-cgi/scripts/5c5dd728/cloudflare-static/email-decode.min.js"></script>