shell进阶1

.    简单的命令跟踪:

方式一:sh -x ./xx.sh  -x选项将打开脚本的执行跟踪功能

方式二:

set -x                                   #打开跟踪功能

echo 1st echo                     #将被打印输出的Shell命令

set +x                                  #Shell命令也将被打印输出

echo 2nd echo                    #Shell命令将不再被打印输出。

 

.    使用cut命令选定字段

cut 

-d : 

-f 1,5 

-f 3-   

 

-c 1-4     -c以字符数量为标量

-c-4        

-c4-         

-c1,4       

-c1-4,5  

 

.    计算行数、字数以及字符数:

echo This is a test  | wc

echo This is a test  | wc -l 统计行

echo This is a test  | wc -w 统计单词数

echo This is a test  | wc -c 统计字符数

 

.提取开头或结尾数行

head -n 5 /etc/passwd 

tail -n 5 /etc/passwd  

 

. grep家族:

 1.  grep退出状态:

    0: 表示成功;

    1: 规则不存在;

    2: 文件不存在;

echo $? 查看退出状态

 

2.grep中应用正则表达式

grep NW testfile      #打印所有包含NW的行。

grep '^n' testfile    #打印出以n开头的行。

grep '4$' testfile    #打印出以4结尾的行

grep '5\..' testfile  #打印出第一个字符是5,后面跟着一个.字符。

grep '\.5' testfile   #打印出所有包含.5的行。

grep '^[we]' testfile  #打印出所有以we开头的行。

grep '[^0-9]' testfile  #打印出所有不是以0-9开头的行。

grep '[A-Z][A-Z] [A-Z]' testfile  #打印出所有包含前两个字符是大写字符,后面紧跟一个空格及一个大写字母的行。

当前的语言环境会影响大小写的输出

grep '[a-z]\{9\}' testfile  #打印所有至少有9个连续小写字符的字符串的行。

grep '\(3\)\.[0-9].*\1    *\1' testfile 

grep '\<north' testfile    #打印所有以north开头的单词的行

grep '\<north\>' testfile  #打印所有包含单词north的行。

grep '^n\w*' testfile      #第一个字符是n,后面是任意字母或者数字

 

3.  扩展grep #egrep = grep -E

主要好处是增加了额外的正则表达式元字符集

egrep 'NW|EA' testfile     #打印所有包含NWEA的行

grep 'NW\|EA' testfile     #对于标准grep,如果在扩展元字符前面加\grep会自动启用扩展选项-E

 

egrep    '3+' testfile

grep       '3\+' testfile        #3条命令将会打印出相同的结果,即所有包含一个或多个3的行。

 

egrep '2\.?[0-9]' testfile 

grep '2\.\?[0-9]' testfile #首先含有2字符,其后紧跟着0个或1个点,后面再是09之间的数字。

 

egrep '(no)+' testfile

grep '\(no\)\+' testfile   #打印一个或者多个连续的no的行

 

egrep'\w+\W+[ABC]' testfile #首先是字母,紧跟着非字母数字,ABC

 

egrep 'w(es)t.*\1' testfile

 

grep常用的命令行选项:

-c 只显示有多少行匹配,而不具体显示匹配的行

-h 不显示文件名

-i 在字符串比较的时候忽略大小写

-l 只显示包含匹配模板的行的文件名清单

-L 只显示不包含匹配模板的行的文件名清单

-n 在每一行前面打印改行在文件中的行数

-v 反向检索,只显示不匹配的行

-w 只显示完整单词的匹配

-x 只显示完整行的匹配

-r/-R 如果文件参数是目录,该选项将递归搜索该目录下的所有子目录和文件

 -C 2  打印匹配行及其上下各两行

 -B 2  打印匹配行及其前两行

-A 2 打印匹配行及其后两行

 

. 流编辑器sed:

 sed一次处理一行文件并把输出送往屏幕。

sed把当前处理的行存储在临时缓冲区中,称为模式空间(pattern space)

一旦sed完成对模式空间中的行的处理,模式空间中的行就被送往屏幕。

行被处理完成之后,就被移出模式空间,程序接着读入下一行,处理,显示,移出......文件输入的最后一行被处理完以后sed结束。

通过存储每一行在临时缓冲区,然后在缓冲区中操作该行,保证了原始文件不会被破坏。

 

1.  sed的命令和选项:

 

a\  在当前行的后面加入一行或者文本。

c\  用新的文本改变或者替代本行的文本。

d  从pattern space位置删除行。

i\  在当前行的上面插入文本。

h  拷贝pattern space的内容到holding buffer(特殊缓冲区)

H  追加pattern space的内容到holding buffer

g  获得holding buffer中的内容,并替代当前pattern space中的文本。

G  获得holding buffer中的内容,并追加到当前pattern space的后面。

n  读取下一个输入行,用下一个命令处理新的行而不是用第一个命令。

p  打印pattern space中的行。

P  打印pattern space中的第一行。

q  退出sed

w file  写并追加pattern spacefile的末尾。

!  表示后面的命令对所有没有被选定的行发生作用。

s/re/string  用string替换正则表达式re

=  打印当前行号码。

 

替换标记  

g  行内全面替换,如果没有g,只替换第一个匹配。

p  打印行。

x  互换pattern spaceholding buffer中的文本。

y  把一个字符翻译为另一个字符(但是不能用于正则表达式)

 

选项  

-e  允许多点编辑。

-n  取消默认输出。

 

 sed '/north/p' testfile  #sed除了打印所有行之外,还有打印匹配行。

在没有-n的时候,包含模板的行被打印两次,但是在使用-n的时候将只打印包含模板的行

 

sed -n '/north/p' testfile

sed '3d' testfile   #第三行被删除,其他行默认输出到屏幕。

sed '3,$d' testfile   #从第三行删除到最后一行,其他行被打印

sed '$d' testfile     #删除最后一行,其他行打印。

sed '/north/d' testfile #删除所有包含north的行,其他行打印

 

sed 's/west/north/g' testfile 

s表示替换,g表示命令作用于整个当前行。存在多个west,都将被替换为north,否则只替换第一个匹配。

sed -n 's/^west/north/p' testfile

sed 's/[0-9][0-9]$/&.5/' testfile 所有以两个数字结束的行,最后的数字都将被它们自己替换,且追加.5

sed -n 's/Hemenway/Jones/gp' testfile

sed -n 's/\(Mar\)got/\1lianne/p' testfile

 

sed -n '/west/,/east/p' testfile

所有在模板westeast所确定的范围内的行都被打印,

如果west出现在esst后面的行中,从west开始到下一个east,无论这个east出现在哪里,二者之间的行都被打印,

即使从west开始到文件的末尾还没有出现east,那么从west到末尾的所有行都将打印。

 

sed -n '5,/^northeast/p' testfile  #打印从第五行开始到第一个以northeast开头的行之间的所有行。

sed -e '1,3d' -e 's/Hemenway/Jones/' testfile #第一个编辑命令是删除第一到第三行。第二个编辑命令是用Jones替换Hemenway

sed -n '/north/w newfile' testfile #将所有匹配含有north的行写入newfile中。

 

sed '/eastern/i\ xinjiadeneirong' testfile   #i是插入命令,在匹配模式行前插入文本。

sed -n '/eastern/{n;s/AM/Archie/;p}' testfile 

n表示定位到匹配行的下一行

p-n选项的合用,则只是打印作用到的行。

找到匹配模式eastern的行后,执行后面花括号中的一组命令,每个命令之间用逗号分隔

 

sed '2q' testfile  #打印完第二行后退出。

sed '/Lewis/{s/Lewis/Joseph/;q;}' testfile  当模板Lewis在某一行被匹配,替换命令首先将Lewis替换为Joseph,然后再用q退出sed

 

sed -e '/northeast/h' -e '$G' testfile northeast追加到行末

sed -e '/WE/{h;d;}' -e '/CT/{G;}' testfile  WE所在的行被移动并追加到包含CT行的后面

sed -e '/northeast/h' -e '$g' testfile 包含模板northeast的行被复制并覆盖了文件的末尾行。

sed -e '/WE/{h;d;}' -e '/CT/{g;}' testfile WE的行都将被移动并覆盖包含CT的行

sed -e '/Patricia/h' -e '/Margot/x' -e '$G' testfile

 

.  awk实用功能:

awk也是逐行扫描文件,寻找匹配特定模板的行,并在这些行上运行“选择”动作。

如果一个模板没有指定动作,这些匹配的行就被显示在屏幕上。

如果一个动作没有模板,所有被动作指定的行都被处理。

 

/> cat employees

Tom Jones         4424    5/12/66         543354

Mary Adams      5346    11/4/63         28765

Sally Chang       1654    7/22/54         650000

Billy Black         1683    9/23/44         336500

 

 1.  awk的基本格式:

awk 'pattern' filename

awk '{action}' filename

awk 'pattern {action}' filename

 

awk '/Mary/' employees   #打印所有包含模板Mary的行。

awk '{print $1}' employees 

awk '/Sally/{print $1, $2}' employees #打印包含模板Sally的行的第一、第二个域字段。

 

2.  awk的格式输出:

date | awk '{print "Month: " $2 "\nYear: " $6}'

awk '/Sally/{print "\t\tHave a nice day, " $1,$2 "\!"}' employees

awk 'BEGIN { OFMT="%.2f"; print 1.2456789, 12E-2}' 打印小数点后两位

 

printf

%c 打印单个ASCII字符。 printf("The character is %c.\n",x) The character is A.

%d 打印十进制数。 printf("The boy is %d years old.\n",y) The boy is 15 years old.

%e 打印用科学记数法表示的数。 printf("z is %e.\n",z) z is 2.3e+01.

%f 打印浮点数。 printf("z is %f.\n",z) z is 2.300000

%o 打印八进制数。 printf("y is %o.\n",y) y is 17.

%s 打印字符串。 printf("The name is %s.\n",$1); The name is Bob Smith.

%x 打印十六进制数。 printf("y is %x.\n",y) y is f.

 

echo "Linux" | awk '{printf "|%-15s|\n", $1}' #%-15s表示保留15个字符的空间,同时左对齐。

echo "Linux" | awk '{printf "|%15s|\n", $1}'    # %-15s表示保留15个字符的空间,同时右对齐。

awk '{printf "The name is %-15s ID is %8d\n", $1,$3}' employees %8d表示数字右对齐,保留8个字符的空间

 

3.  awk中的记录和域:

awk '{print $0}' employees  #$0变量是指整条记录

 

变量NR(Number of Record),记录每条记录的编号

awk '{print NR, $0}' employees

awk '{print $0,NF}' employees

 

sed 's/[[:space:]]\+\([0-9]\)/:\1/g;w employees2' employees #根据employees生成employees2

    Tom Jones:4424:5/12/66:543354

    Mary Adams:5346:11/4/63:28765

    Sally Chang:1654:7/22/54:650000

    Billy Black:1683:9/23/44:336500

 

awk -F: '/Tom Jones/{print $1,$2}' employees2  #这里-F选项后面的字符表示分隔符。

    Tom Jones 4424

 

变量OFS(Output Field Seperator)表示输出字段间的分隔符,缺省是空格。

awk -F: '{OFS = "?"};  /Tom/{print $1,$2 }' employees2

Tom Jones?4424

 

awk '$3 < 4000 {print}' employees

 

awk '$3 < 4000 && /Sally/ {print}' employees

 

 

4.  匹配操作符:

" ~ " 用来在记录或者域内匹配正则表达式。

" !~ "表示不匹配的意思

 

awk '$1 ~ /[Bb]ill/' employees      #显示所有第一个域匹配Billbill的行

awk '$1 !~ /[Bb]ill/' employees     #显示所有第一个域不匹配Billbill的行

 

5.  awk的基本应用实例:

awk '/^north/' testfile            #打印所有以north开头的行。

awk '/^(no|so)/' testfile          #打印所有以sono开头的行

awk '$5 ~ /\.[7-9]+/' testfile     #第五个域字段匹配包含.(),后面是7-9的数字。

awk '$8 ~ /[0-9][0-9]$/{print $8}' testfile  #第八个域以两个数字结束的打印。

 

.  awk表达式功能:

 

 /> cat employees

    Tom Jones        4424    5/12/66         543354

    Mary Adams      5346    11/4/63         28765

    Sally Chang       1654    7/22/54         650000

    Billy Black         1683    9/23/44         336500

 

 1.  比较表达式:

< 小于 x < y

<= 小于等于 x <= y

== 等于 x == y

!= 不等于 x != y

>= 大于等于 x >= y

> 大于 x > y

~ 匹配 x ~ /y/

!~ 不匹配 x !~ /y/

 

awk '$3 == 5346' employees        #打印第三个域等于5346的行。

awk '$3 > 5000 {print $1}' employees   #打印第三个域大于5000的行的第一个域字段。

awk '$2 ~ /Adam/' employess       #打印第二个域匹配Adam的行。

 

2.  条件表达式:

 

 /> cat testfile

    northwest     NW        Charles Main             3.0        .98        3        34

    western        WE        Sharon Gray             5.3        .97         5        23

    southwest     SW        Lewis Dalsass           2.7        .8          2        18

    southern       SO        Suan Chin                 5.1        .95        4        15

    southeast      SE        Patricia Hemenway     4.0        .7          4        17

    eastern         EA        TB Savage                 4.4        .84        5        20

    northeast      NE        AM Main Jr.                5.1       .94         3        13

    north            NO        Margot Weber           4.5       .89         5        9

    central          CT        Ann Stephens            5.7       .94         5        13

 

awk 'NR <= 3 {print ($7 > 4 ? "high "$7 : "low "$7) }' testfile #前三行,域7是否大于4

 

3.  数学表达式:

+ 加 x + y

- 减 x - y

* 乘 x * y

/ 除 x / y

% 取余 x % y

^ 乘方 x ^ y

 

awk '/southern/{print $5 + 10}' testfile   #如果记录包含正则表达式southern,第五个域就加10并打印。

awk '/southern/{print $8 /2 }' testfile    #如果记录包含正则表达式southern,第八个域除以2并打印。

 

4.  逻辑表达式:

&& 逻辑与 a && b

|| 逻辑或 a || b

! 逻辑非 !a

 

awk '$8 > 10 && $8 < 17' testfile    #打印出第八个域的值大于10小于17的记录。

awk '$2 == "NW" || $1 ~ /south/ {print $1,$2}' testfile 打印 第二个域等于NW,或者第一个域匹配south的行 的第一、第二个域。

awk '!($8 > 13) {print $8}' testfile  #打印第八个域字段不大于13的行的第八个域。

 

5.  范围模板:

awk '/^western/,/^eastern/ {print $1}' testfile  #打印以western开头到eastern开头的记录的第一个域。

 

6.  赋值符号:

awk '$3 == "Ann" { $3 = "Christian"; print}' testfile

#找到第三个域等于Ann的记录,然后给该域重新赋值为Christian,之后再打印输出该记录。

 

awk '/Ann/{$8 += 12; print $8}' testfile 

#找到包含Ann的记录,并将该条记录的第八个域的值+=12,最后再打印输出。

 

posted @ 2016-08-06 23:20  小_龟  阅读(263)  评论(0编辑  收藏  举报