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 #打印出所有以w或e开头的行。
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 #打印所有包含NW或EA的行
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个点,后面再是0和9之间的数字。
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 space到file的末尾。
! 表示后面的命令对所有没有被选定的行发生作用。
s/re/string 用string替换正则表达式re。
= 打印当前行号码。
替换标记
g 行内全面替换,如果没有g,只替换第一个匹配。
p 打印行。
x 互换pattern space和holding 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
所有在模板west和east所确定的范围内的行都被打印,
如果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 #显示所有第一个域匹配Bill或bill的行
awk '$1 !~ /[Bb]ill/' employees #显示所有第一个域不匹配Bill或bill的行
5. awk的基本应用实例:
awk '/^north/' testfile #打印所有以north开头的行。
awk '/^(no|so)/' testfile #打印所有以so和no开头的行
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,最后再打印输出。