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/1895900612235685888.htm"
                           title="oracle数据库只导出索引,oracle数据库全库的导出导入实战手册" target="_blank">oracle数据库只导出索引,oracle数据库全库的导出导入实战手册</a>
                        <span class="text-muted">Lorraine张</span>
<a class="tag" taget="_blank" href="/search/oracle%E6%95%B0%E6%8D%AE%E5%BA%93%E5%8F%AA%E5%AF%BC%E5%87%BA%E7%B4%A2%E5%BC%95/1.htm">oracle数据库只导出索引</a>
                        <div>Oracle数据库导入导出(expdp/impdb)1、全库导出(expdp参考shell脚本)#!/bin/bash#导入环境变量source/home/oracle/.bash_profileexportORACLE_BASE=/u01/app/oracleexportORACLE_HOME=/u01/app/oracle/product/11.2.0/db_1/exportPATH=$PAT</div>
                    </li>
                    <li><a href="/article/1895811981168930816.htm"
                           title="linux shell编程" target="_blank">linux shell编程</a>
                        <span class="text-muted">野生java研究僧</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><a class="tag" taget="_blank" href="/search/bash/1.htm">bash</a><a class="tag" taget="_blank" href="/search/%E8%BF%90%E7%BB%B4/1.htm">运维</a>
                        <div>linuxshell编程1.shell脚本概述2.脚本的调用形式3.shell脚本语法3.1脚本开头标识3.2脚本注释3.3给脚本加上可执行权限3.4shell脚本的运行方式3.5检测脚本是否正确3.6重定向的使用3.7获取上一条命令的执行结果4.变量4.1变量的定义和使用4.2从键盘上读取变量:4.3读取多个变量的值:4.4查看环境变量:4.5注意事项4.6判断变量是否存在4.7字符串操作4.8</div>
                    </li>
                    <li><a href="/article/1895719712902410240.htm"
                           title="linux shell脚本 cp,shell命令之cp" target="_blank">linux shell脚本 cp,shell命令之cp</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/shell%E8%84%9A%E6%9C%AC/1.htm">shell脚本</a><a class="tag" taget="_blank" href="/search/cp/1.htm">cp</a>
                        <div>操作系统为macOS10.12.4cp为复制命令,实际中分为文件间的复制,目录间的复制,文件到目录的复制以及链接的复制。文件间的复制cpfile1file2如果file2不存在,就先创建file2,然后把file1内容复制到file2中如果file2存在,把把file1的内容覆盖file2的内容覆盖file2的内容,有时候并不是所希望的参数-i可以提示是否覆盖file2参数-n让复制命令不覆盖fi</div>
                    </li>
                    <li><a href="/article/1895665869804072960.htm"
                           title="Windows和AD域提权枚举脚本及工具介绍" target="_blank">Windows和AD域提权枚举脚本及工具介绍</a>
                        <span class="text-muted">vortex5</span>
<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/windows/1.htm">windows</a>
                        <div>在Windows和ActiveDirectory(AD)域环境中,权限提升和枚举是渗透测试的关键部分。为了有效进行这些操作,使用特定的工具和脚本可以帮助你识别和利用系统中的漏洞。以下是一些常用于Windows和AD域环境中的权限提升和枚举脚本工具:Windows环境中的提权枚举脚本PowerUp描述:PowerUp是一个PowerShell脚本,专注于在Windows系统中查找权限提升漏洞。它能够</div>
                    </li>
                    <li><a href="/article/1895545944414416896.htm"
                           title="判断一个文件中以三个#号开头有多少行的shell脚本怎么写" target="_blank">判断一个文件中以三个#号开头有多少行的shell脚本怎么写</a>
                        <span class="text-muted">taoyong001</span>
<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>在Linux中,你可以使用grep命令结合正则表达式来统计一个文件中以三个#号开头的行数。以下是一个简单的命令:grep-c'^###'filename这里的grep是搜索工具,-c选项表示统计匹配的行数,'###'是正则表达式,表示行的开头()紧跟着三个#号(###),filename是你要搜索的文件名。例如,如果你的文件名是example.txt,你可以运行:grep-c'^###'examp</div>
                    </li>
                    <li><a href="/article/1895541028509773824.htm"
                           title="Linux系统中shell处理变量详解" target="_blank">Linux系统中shell处理变量详解</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>Linux系统中shell处理变量详解一、shell中变量介绍1.1变量简介1.2环境变量和本地变量1.3预定义变量二、本地变量的使用2.1本地变量介绍2.2定义本地变量2.3查看本地变量2.4取消环境变量2.5查询变量值2.6本地变量的使用三、环境变量3.1环境变量介绍3.2定义环境变量3.3查看环境变量3.4取消环境变量3.5查询设置的环境变量值3.6变量在shell脚本使用四、使用echo输</div>
                    </li>
                    <li><a href="/article/1895404378400026624.htm"
                           title="【一文入门】shell语法进阶篇" target="_blank">【一文入门】shell语法进阶篇</a>
                        <span class="text-muted">worxfr</span>
<a class="tag" taget="_blank" href="/search/linux/1.htm">linux</a><a class="tag" taget="_blank" href="/search/shell/1.htm">shell</a>
                        <div>Shell脚本的进阶语法涉及更复杂的编程结构、数据处理和系统交互。以下是一些进阶的Shell编程概念和技巧,帮助你提升编写复杂脚本的能力。前置知识【一文入门】shell基础语法【一文入门】shell语法进阶篇1.高级变量操作间接引用:通过变量名的变量名来访问其值。var_name="greeting"greeting="Hello,World!"echo${!var_name}#输出Hello,W</div>
                    </li>
                    <li><a href="/article/1895350024380936192.htm"
                           title="【Linux】Ubuntu 服务器中 LAMP 服务器安装与配置" target="_blank">【Linux】Ubuntu 服务器中 LAMP 服务器安装与配置</a>
                        <span class="text-muted">练小杰</span>
<a class="tag" taget="_blank" href="/search/Linux%E9%9B%B6%E5%9F%BA%E7%A1%80%E5%BC%80%E5%A7%8B/1.htm">Linux零基础开始</a><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/ubuntu/1.htm">ubuntu</a><a class="tag" taget="_blank" href="/search/sql/1.htm">sql</a><a class="tag" taget="_blank" href="/search/php/1.htm">php</a><a class="tag" taget="_blank" href="/search/mysql/1.htm">mysql</a><a class="tag" taget="_blank" href="/search/%E8%BF%90%E7%BB%B4/1.htm">运维</a>
                        <div>ℹ️大家好,我是练小杰,今天是二月份的最后一天,抓住2月的尾巴,passion!!本文是针对Linux系统中LAMP服务器安装与配置更加深入的讨论,后续有相关知识会持续更新,谢谢各位的支持前情回顾:【Ubuntu服务器的安装和配置管理】Linux专栏:【Linux零基础开始】【Shell脚本编程】【Linux文件系统】主页:【练小杰的CSDN】LAMP服务器主页:【[练小杰的CSDN](https</div>
                    </li>
                    <li><a href="/article/1895288610295443456.htm"
                           title="【linux自动化实践】linux shell 脚本 替换某文本" target="_blank">【linux自动化实践】linux shell 脚本 替换某文本</a>
                        <span class="text-muted">忙碌的菠萝</span>
<a class="tag" taget="_blank" href="/search/linux%E8%87%AA%E5%8A%A8%E5%8C%96%E5%AE%9E%E8%B7%B5/1.htm">linux自动化实践</a><a class="tag" taget="_blank" href="/search/linux/1.htm">linux</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/%E8%BF%90%E7%BB%B4/1.htm">运维</a>
                        <div>在Linuxshell脚本中,可以使用sed命令来替换文本。以下是一个基本的例子,它将在文件example.txt中查找文本old_text并将其替换为new_textsed-i's/old_text/new_text/g'example.txt解释:sed:是streameditor的缩写,用于处理文本数据。-i:表示直接修改文件内容。s:表示替换操作。old_text:要被替换的文本。new_</div>
                    </li>
                    <li><a href="/article/1895165150281920512.htm"
                           title="Python自动化运维实战,怎么构建分布式质量监控平台" target="_blank">Python自动化运维实战,怎么构建分布式质量监控平台</a>
                        <span class="text-muted">好知识传播者</span>
<a class="tag" taget="_blank" href="/search/Python%E5%AE%9E%E4%BE%8B%E5%BC%80%E5%8F%91%E5%AE%9E%E6%88%98/1.htm">Python实例开发实战</a><a class="tag" taget="_blank" href="/search/%E8%BF%90%E7%BB%B4/1.htm">运维</a><a class="tag" taget="_blank" href="/search/python/1.htm">python</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/%E5%88%86%E5%B8%83%E5%BC%8F%E8%B4%A8%E9%87%8F%E7%9B%91%E6%8E%A7%E5%B9%B3%E5%8F%B0/1.htm">分布式质量监控平台</a><a class="tag" taget="_blank" href="/search/linux/1.htm">linux</a>
                        <div>注意:本文的下载教程,与以下文章的思路有相同点,也有不同点,最终目标只是让读者从多维度去熟练掌握本知识点。下载教程:Python自动化运维项目开发实战_构建分布式质量监控平台_编程案例解析实例课程教程.pdf一、引言随着企业业务的不断扩展和复杂化,系统运维面临着越来越多的挑战。传统的运维方式已经无法满足现代企业的需求,因此,自动化运维成为了企业提升运维效率、保障系统稳定性的重要手段。在自动化运维中</div>
                    </li>
                    <li><a href="/article/1895137517343141888.htm"
                           title="PowerShell 脚本实现计算机加入AD域" target="_blank">PowerShell 脚本实现计算机加入AD域</a>
                        <span class="text-muted">winkel_wang</span>
<a class="tag" taget="_blank" href="/search/Windows/1.htm">Windows</a><a class="tag" taget="_blank" href="/search/PowerShell/1.htm">PowerShell</a><a class="tag" taget="_blank" href="/search/windows/1.htm">windows</a><a class="tag" taget="_blank" href="/search/%E8%BF%90%E7%BB%B4/1.htm">运维</a>
                        <div>要将Windows计算机加入ActiveDirectory(AD)域,可以使用PowerShell脚本来自动化这个过程。以下是一个示例脚本,它将计算机加入指定的AD域,并自动重启计算机以完成加入过程。PowerShell脚本示例定义变量$domainName=“yourdomain.com”#替换为你的域名$domainAdmin=“adminuser”#替换为有权限加入域的域管理员账户$doma</div>
                    </li>
                    <li><a href="/article/1895106208788967424.htm"
                           title="linux中的sh脚本语法" target="_blank">linux中的sh脚本语法</a>
                        <span class="text-muted"></span>

                        <div>在Linux环境下,Shell脚本是一种用于自动化执行命令的强大工具。它不仅简化了日常任务,还能通过组合命令实现复杂的操作。下面详细解析一些常见的语法要点,并通过代码示例和详细解释,帮助你全面掌握Shell脚本的基础语法。1.Shebang行代码示例:#!/bin/bash详细解释:这一行位于脚本文件的最开始,用于指定脚本所使用的解释器。/bin/bash表示使用Bash解释器来执行脚本,确保脚本</div>
                    </li>
                    <li><a href="/article/1894868280766689280.htm"
                           title="jenkins自动打包vuejs部署到docker" target="_blank">jenkins自动打包vuejs部署到docker</a>
                        <span class="text-muted">戚辰先生丶</span>

                        <div>流程1、配置jenkins-git项目克隆2、配置运行jenkins的shell脚本3、编写Dockerfile自动制作镜像并复制jenkins打包好的文件到容器里4、jenkins负责运行docker命令进行停止、删除原有镜像,并重新运行镜像docker部署jenkinsdockerrun-d-p8086:8080-p50000:50000-v/var/run/docker.sock:/var/</div>
                    </li>
                    <li><a href="/article/1894856431325212672.htm"
                           title="【shell笔记】Linux Shell脚本编程入门知识点全面涵盖" target="_blank">【shell笔记】Linux Shell脚本编程入门知识点全面涵盖</a>
                        <span class="text-muted">阿毛啊阿阿</span>
<a class="tag" taget="_blank" href="/search/shell/1.htm">shell</a>
                        <div>本文是我对白树明老师shell课程笔记的总结,课程链接:https://www.bilibili.com/video/BV1j541157Sr?from=search&seid=9757674743771615780一:shell是什么?生成shell脚本shell是什么?1shell是一个程序,采用C语言编写,是用户和Linux内核沟通的桥梁。2shell脚本就是将完成一个任务的所有命令按照执行</div>
                    </li>
                    <li><a href="/article/1894523420868145152.htm"
                           title="服务器/mac m1配置python环境" target="_blank">服务器/mac m1配置python环境</a>
                        <span class="text-muted">LoveSeven.Lin</span>
<a class="tag" taget="_blank" href="/search/macos/1.htm">macos</a><a class="tag" taget="_blank" href="/search/python/1.htm">python</a><a class="tag" taget="_blank" href="/search/%E5%BC%80%E5%8F%91%E8%AF%AD%E8%A8%80/1.htm">开发语言</a>
                        <div>目录服务器配置环境一、安装miniconda二、创建环境三、激活环境四、conda安装Macm1配置环境一、安装Miniforge3二、创建环境三、激活环境四、安装tensorflow五、测试运行服务器配置环境一、安装miniconda#step1:获取安装shell脚本文件wgethttps://repo.continuum.io/miniconda/Miniconda3-latest-Linu</div>
                    </li>
                    <li><a href="/article/1894475766125621248.htm"
                           title="ansible playbook play task执行顺序" target="_blank">ansible playbook play task执行顺序</a>
                        <span class="text-muted">Mary Ling</span>
<a class="tag" taget="_blank" href="/search/DEVOPS/1.htm">DEVOPS</a><a class="tag" taget="_blank" href="/search/devops/1.htm">devops</a>
                        <div>当我们使用ansible-playbook执行playbook,我们可以指定一个或者多个playbook,而一个playbook中可以有多个play,这些play下面又会存在一个或者多个task,这些task会调用module去执行shell脚本,或者文件拷贝等等各种命令,具体可参考ansibleplaybook基本概念我们知道在配置play的task时,可以配置pre_tasks,task和po</div>
                    </li>
                    <li><a href="/article/1894455603070300160.htm"
                           title="【C++】Linux系统编程入门" target="_blank">【C++】Linux系统编程入门</a>
                        <span class="text-muted">饮酒吃肉飞奔</span>
<a class="tag" taget="_blank" href="/search/Linux%2FC%2FC%2B%2B/1.htm">Linux/C/C++</a><a class="tag" taget="_blank" href="/search/c%2B%2B/1.htm">c++</a><a class="tag" taget="_blank" href="/search/linux/1.htm">linux</a><a class="tag" taget="_blank" href="/search/%E5%BC%80%E5%8F%91%E8%AF%AD%E8%A8%80/1.htm">开发语言</a><a class="tag" taget="_blank" href="/search/c%E8%AF%AD%E8%A8%80/1.htm">c语言</a><a class="tag" taget="_blank" href="/search/vscode/1.htm">vscode</a><a class="tag" taget="_blank" href="/search/ubuntu/1.htm">ubuntu</a>
                        <div>提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档文章目录前言一常用的Linux系统命令符二GCC三静态库四动态库(共享库)动态库五动态库和静态库的区别六Makefile变量模式匹配Makefile的函数七GDB调试设置断点调试命令八文件IO九虚拟地址空间文件描述符opencreatecopylseekstatls-l的实现文件属性操作函数目录操作函数目录遍历函数dupdup2函数f</div>
                    </li>
                    <li><a href="/article/1894185170467090432.htm"
                           title="Spark性能调优方法总结" target="_blank">Spark性能调优方法总结</a>
                        <span class="text-muted">Cynthiaaaaalxy</span>
<a class="tag" taget="_blank" href="/search/spark/1.htm">spark</a><a class="tag" taget="_blank" href="/search/%E5%A4%A7%E6%95%B0%E6%8D%AE/1.htm">大数据</a><a class="tag" taget="_blank" href="/search/%E5%88%86%E5%B8%83%E5%BC%8F/1.htm">分布式</a>
                        <div>1、资源分配优化  Spark的分配资源主要就是executor、cpuperexecutor、memoryperexecutor、drivermemory等的调节,我们在生产环境中,提交spark作业时,用的spark-submitshell脚本,里面调整对应的参数:/usr/local/spark/bin/spark-submit–confspark.default.parallelism=1</div>
                    </li>
                    <li><a href="/article/1893814613384949760.htm"
                           title="Shell脚本传递参数的4种方式" target="_blank">Shell脚本传递参数的4种方式</a>
                        <span class="text-muted">yan_baby_liu</span>
<a class="tag" taget="_blank" href="/search/Shell/1.htm">Shell</a><a class="tag" taget="_blank" href="/search/linux/1.htm">linux</a>
                        <div>#脚本内容script.sh【使用位置参数】#!/bin/bashif[$1-gt18];thenecho"Youareanadult."elseecho"Youarenotanadultyet."fi#脚本调用./script.sh19#for语句foriin12345;doecho$idone#while语句【使用了变量】i=0while[$i-lt10];doecho$ii=$((i+1))</div>
                    </li>
                    <li><a href="/article/1893800111931191296.htm"
                           title="Shell:bash脚本入门" target="_blank">Shell:bash脚本入门</a>
                        <span class="text-muted">geek_Chen01</span>
<a class="tag" taget="_blank" href="/search/bash/1.htm">bash</a>
                        <div>Shell入门–TheMissingSemesterofYourCSEducation一、Shell脚本基础1.1变量与字符串#正确赋值(无空格)foo=bar#错误示例(带空格会报错)foo=bar#双引号支持变量扩展echo"Value:$foo"#输出Value:bar#单引号保持原样echo'Value:$foo'#输出Value:$foo1.2特殊变量变量描述$0脚本名称$1-$9第1-</div>
                    </li>
                    <li><a href="/article/1893572925198495744.htm"
                           title="Jenkins 构建 Unity打包APK" target="_blank">Jenkins 构建 Unity打包APK</a>
                        <span class="text-muted">[奋斗不止]</span>
<a class="tag" taget="_blank" href="/search/jenkins/1.htm">jenkins</a><a class="tag" taget="_blank" href="/search/Unity/1.htm">Unity</a><a class="tag" taget="_blank" href="/search/jenkins/1.htm">jenkins</a><a class="tag" taget="_blank" href="/search/unity/1.htm">unity</a><a class="tag" taget="_blank" href="/search/%E6%89%B9%E5%A4%84%E7%90%86/1.htm">批处理</a><a class="tag" taget="_blank" href="/search/%E7%BC%96%E8%BE%91%E5%99%A8/1.htm">编辑器</a>
                        <div>Jenkins构建Unity打包APK一、创建一个Pipeline任务在项目跟目录创建Pipeline脚本jenkins_scripts\Pipeline\android_master_pipeline脚本如下//AndroidMaster打包apkpipeline{agentanystages{stage('TestParameter'){steps{script{//shell脚本目录ANDR</div>
                    </li>
                    <li><a href="/article/1893352659465859072.htm"
                           title="Linux之Shell:Shell/Shell脚本(sh)的简介、使用方法、案例应用之详细攻略" target="_blank">Linux之Shell:Shell/Shell脚本(sh)的简介、使用方法、案例应用之详细攻略</a>
                        <span class="text-muted">一个处女座的程序猿</span>
<a class="tag" taget="_blank" href="/search/Tool%2FIDE/1.htm">Tool/IDE</a><a class="tag" taget="_blank" href="/search/etc/1.htm">etc</a><a class="tag" taget="_blank" href="/search/%E6%88%90%E9%95%BF%E4%B9%A6%E5%B1%8B/1.htm">成长书屋</a><a class="tag" taget="_blank" href="/search/linux/1.htm">linux</a><a class="tag" taget="_blank" href="/search/shell/1.htm">shell</a><a class="tag" taget="_blank" href="/search/bash/1.htm">bash</a>
                        <div>Linux之Shell:Shell/Shell脚本(sh)的简介、使用方法、案例应用之详细攻略目录相关文章Windows之Batch:Batch批处理脚本(bat/cmd)的简介、使用方法、案例应用之详细攻略Linux:Linux系统的简介、基础知识、最强学习路线(以Ubuntu系统为例—安装/各自命令行技能/文件系统/Shell脚本编程/权限网络和系统管理/高级语言编程)、常用案例(图文教程)之</div>
                    </li>
                    <li><a href="/article/1893332099595825152.htm"
                           title="《Linux运维总结:基于Ubuntu 22.04+x86_64架构CPU部署etcd 3.5.15二进制分布式集群》" target="_blank">《Linux运维总结:基于Ubuntu 22.04+x86_64架构CPU部署etcd 3.5.15二进制分布式集群》</a>
                        <span class="text-muted">东城绝神</span>
<a class="tag" taget="_blank" href="/search/%E3%80%8ALinux%E8%BF%90%E7%BB%B4%E5%AE%9E%E6%88%98%E6%80%BB%E7%BB%93%E3%80%8B/1.htm">《Linux运维实战总结》</a><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/ubuntu/1.htm">ubuntu</a><a class="tag" taget="_blank" href="/search/etcd/1.htm">etcd</a>
                        <div>总结:整理不易,如果对你有帮助,可否点赞关注一下?更多详细内容请参考:《Linux运维篇:Linux系统运维指南》一、功能简介1、什么是etcdetcd是一个分布式、可靠的键值存储系统,用于分布式系统中存储关键核心数据。它由CoreOS开发,并且是开源的,授权协议为Apache许可证。etcd内部采用了Raft一致性算法,可以实现配置共享和服务发现。etcd中文文档可参考如下:Etcd中文文档或者</div>
                    </li>
                    <li><a href="/article/1893165505112502272.htm"
                           title="2025年普通人转向人工智能运维(AIOps)学习建议(附最新技术实践与资源)" target="_blank">2025年普通人转向人工智能运维(AIOps)学习建议(附最新技术实践与资源)</a>
                        <span class="text-muted">emmm形成中</span>
<a class="tag" taget="_blank" href="/search/%E4%BA%BA%E5%B7%A5%E6%99%BA%E8%83%BD/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>
                        <div>2025年普通人转向人工智能运维(AIOps)学习建议(附最新技术实践与资源)一、学习路径规划:分阶段掌握核心技能1.基础能力构建(3-6个月)传统运维技能Linux与Shell脚本:掌握Linux系统管理、性能调优及常用命令(如awk、sed处理日志)。监控工具:学习Prometheus、Zabbix等工具,理解指标采集与告警规则配置。自动化运维:熟悉Ansible、Jenkins等工具,编写自</div>
                    </li>
                    <li><a href="/article/1893058553824997376.htm"
                           title="【IT规划设计】IP地址规划参考思路" target="_blank">【IT规划设计】IP地址规划参考思路</a>
                        <span class="text-muted">supportlx</span>
<a class="tag" taget="_blank" href="/search/%E7%BD%91%E7%BB%9C/1.htm">网络</a>
                        <div>1.IP地址规划原则目前集团的IP地址欠缺统一规划,存在分配不合理和不连续情况,极大增加网络运维和系统运维的难度。缺乏IP地址分配和回收的管理机制,容易造成IP地址冲突。不同业务混合在一个VLAN地址段,不同安全域的IP地址范围没有关联规律,比较杂乱,不好记忆,缺乏IP指导规范。需要对IP地址管理进行梳理和规范。新IP地址规划原则如下:新的地址规划将兼容现有的集团地址空间分配原则,同时也会对一些功</div>
                    </li>
                    <li><a href="/article/1893024115019804672.htm"
                           title="《Linux运维总结:基于ARM64+X86_64架构CPU使用docker-compose一键离线部署redis 6.2.14容器版哨兵集群》" target="_blank">《Linux运维总结:基于ARM64+X86_64架构CPU使用docker-compose一键离线部署redis 6.2.14容器版哨兵集群》</a>
                        <span class="text-muted">东城绝神</span>
<a class="tag" taget="_blank" href="/search/%E3%80%8ALinux%E8%BF%90%E7%BB%B4%E5%AE%9E%E6%88%98%E6%80%BB%E7%BB%93%E3%80%8B/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/linux/1.htm">linux</a><a class="tag" taget="_blank" href="/search/%E6%9E%B6%E6%9E%84/1.htm">架构</a><a class="tag" taget="_blank" href="/search/redis/1.htm">redis</a><a class="tag" taget="_blank" href="/search/%E5%93%A8%E5%85%B5%E9%9B%86%E7%BE%A4/1.htm">哨兵集群</a>
                        <div>总结:整理不易,如果对你有帮助,可否点赞关注一下?更多详细内容请参考:《Linux运维篇:Linux系统运维指南》一、部署背景由于业务系统的特殊性,我们需要面向不通的客户安装我们的业务系统,而作为基础组件中的redis针对不同的客户环境需要多次部署集群,作为一个运维工程师,提升工作效率也是工作中的重要一环。所以我觉得有必要针对X86_64+ARM64CPU架构redis6.2.14容器版哨兵集群编</div>
                    </li>
                    <li><a href="/article/1892812191531331584.htm"
                           title="在 CentOS 服务器上自动申请和更新多域名 SSL 证书" target="_blank">在 CentOS 服务器上自动申请和更新多域名 SSL 证书</a>
                        <span class="text-muted">周小码</span>
<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/centos/1.htm">centos</a><a class="tag" taget="_blank" href="/search/ssl/1.htm">ssl</a>
                        <div>本文将介绍如何使用Shell脚本自动化管理多个域名的SSL证书,包括申请、安装和自动更新。背景在运维工作中,经常需要为多个域名申请和更新SSL证书。手动操作不仅繁琐,还容易出错。通过脚本自动化这个过程,可以大大提高工作效率。实现方案我们使用Let’sEncrypt提供的免费证书服务,结合certbot工具来实现证书的申请和更新。脚本支持同时处理多个域名,并设置自动更新任务。1.完整脚本#!/bin</div>
                    </li>
                    <li><a href="/article/1892687734502387712.htm"
                           title="使用shell脚本运行python程序" target="_blank">使用shell脚本运行python程序</a>
                        <span class="text-muted">GiantGo</span>
<a class="tag" taget="_blank" href="/search/%23/1.htm">#</a><a class="tag" taget="_blank" href="/search/Python/1.htm">Python</a><a class="tag" taget="_blank" href="/search/python/1.htm">python</a><a class="tag" taget="_blank" href="/search/%E5%BC%80%E5%8F%91%E8%AF%AD%E8%A8%80/1.htm">开发语言</a>
                        <div>在训练深度学习模型时,为了解放生产力,避免手动调参等,一般写成shell脚本的形式,执行一次shell就可以把所有的python程序给运行完毕。例如,我需要探究batchsize的影响,一般新手入门可能这样做:设置batchsize=8,运行一次main.py程序。设置batchsize=16,运行一次main.py程序。设置batchsize=32,运行一次main.py程序。设置batchsi</div>
                    </li>
                    <li><a href="/article/1892686977543761920.htm"
                           title="shell脚本中激活python环境" target="_blank">shell脚本中激活python环境</a>
                        <span class="text-muted">qq_21478261</span>
<a class="tag" taget="_blank" href="/search/%23/1.htm">#</a><a class="tag" taget="_blank" href="/search/%E7%94%9F%E7%89%A9%E4%BF%A1%E6%81%AF/1.htm">生物信息</a><a class="tag" taget="_blank" href="/search/python/1.htm">python</a><a class="tag" taget="_blank" href="/search/linux/1.htm">linux</a><a class="tag" taget="_blank" href="/search/%E5%BC%80%E5%8F%91%E8%AF%AD%E8%A8%80/1.htm">开发语言</a>
                        <div>sourcepath_activate/activateenv_name其中,必须添加activate的路径path_activate,否则会报找不到activate的error</div>
                    </li>
                    <li><a href="/article/1892678649824473088.htm"
                           title="Shell脚本和Python的工作路径" target="_blank">Shell脚本和Python的工作路径</a>
                        <span class="text-muted">行码棋</span>
<a class="tag" taget="_blank" href="/search/%23/1.htm">#</a><a class="tag" taget="_blank" href="/search/Python/1.htm">Python</a><a class="tag" taget="_blank" href="/search/python/1.htm">python</a>
                        <div>在Linux中,工作目录(WorkingDirectory)是指当前进程执行时所处的目录路径。工作目录会影响文件路径的解析,相对路径是基于工作目录来确定的。场景描述假设在项目根目录/下运行一个位于子目录/home/user/scripts中的Bash脚本script.sh,而该脚本中又调用了一个Python程序program.py。我们需要分析脚本和Python程序的工作目录。1.运行Bash脚本</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>