shell学习笔记

1 篇文章 0 订阅

基础用法:

  1. !/bin/sh #!用来告诉系统它后面的参数是用来执行该文件的程序
  2. 当编辑好脚本时,要执行该脚本,必须有可执行权限,可使用chmod 744 shellTest.sh设置当前用户的可执行权限
  3. ./filename或者sh filename来执行脚本

简单的执行跟踪

set -x打开:使shell显示每个执行到的 命令,并在前面加上”+”,一个加号后面跟一个空格
set +x关闭跟踪
这里写图片描述

命令集合:

< 改变标准输入,将后面的文件作为标准输入
> 改变标准输出,重定向文件如果不存在会自动新建一个,如果文件存在会覆盖原来的内容
>>附加内容到文件末尾,不覆盖原内容,同样,如果文件不存在,会自动新建一个

tr
tr [option] source-char-list replace-char-list
如同过滤器,自标准输入读取字符,再讲结果写到标准输出。任何输入字符只要出现在source-char-list,就会置换成replace-char-list里响应的字符
转换字符,例如大写转换小写,删除字符,以及将一串重复出现的字符浓缩成一个
-c 取source-char-list的反义,tr要转换的字符,变成未在source-char-list中的字符,通常与-d或-s配合使用
-C与-c类似,处理的是字符,而非二进制字节
-d字标准输入中删除source-char-list里所列的字符,而不是转换他们
-s浓缩重复的字符。如果标准输入中连续重复出现source-char-list里所列的字符,将其浓缩成一个

WC
1. wc -l filename 统计总行数
2. wc -w filename 统计总单词数
3. wc -c filename统计总字符数
wc /etc/passwd /etc/group统计两个文件的数据
36 61 1794 /etc/passwd
57 57 784 /etc/group
93 118 2578 total

file
展示文件类型

read
提示用户输入,并将输入赋值给变量 :read a;echo $a

sort filename
对文件内容进行排序

uniq
删除文件中重复出现的行,sort filename | uniq

grep
这里写图片描述

expr
进行数学运算:2+3===》expr 2 “+” 3,符号一定要加引号,数字与引号之间一定要有空格

sed
运作模式:读取每个文件,一次读取一行,将读取的行放到一个内存区域,称为模式空间。内存中的区域在编辑命令下可以修改,所有编辑上的操作都会应用到模式空间,当所有操作完成后,sed会将模式空间的最后内容打印到标准输出,再回到开始处,读取领一行
(-直接覆盖),可以用/或者: ;等作为定界符;在s命令中以g结尾表示的是全局性,如果没有设置g,置灰取代第一个匹配。
cat shellTest.sh | sed ‘s/num=2/num=3/’ >> shellTestNew.sh
可以在结尾指定数字,指示第N个匹配出现才要被取代
sed ‘s/test/modity/2’ 仅替代第二个匹配
-e一次多个替换命令时必须使用
sed -e ‘s/foo/bar/g’ -e ‘s/chicken/cow/g’ sourcefile > destinatefile
sed -e ‘s/toystoy/test/g’ -e ‘s/test/testtttt/g’ zheng.txt
-f从scriptfile中读取编辑命令。有多个命令时好用
file.sed
s/foo/bar/g
s/chicken/cow/g
调用:
sed -f file.sed sourcefile > destinatefile
-n
不是每个最后已修改的结果都正常打印,而是显示以P指定的行
sed -n ‘/HTML/p’ *.html仅显示html这行,相当于模拟grep
匹配特定行:
sed默认会将每一个编辑命令应用到每个输入行,为了限制一条命令要应用到哪些行,只要在命令前置一个地址即可。地址分为以下几种:
1、正则表达式:
将一模式放置到命令之前,可限制命令应用于匹配模式的行,可与s命令搭配使用
s命令里的空模式指的是使用前一个正则表达式
源文件:
toystoy
toystoysdf
atoystoy
ssstoystoy
toyfstoy
toyfdf1stoy
用sed ‘/^t.*y$/s//# xxx/’ zheng.txt命令指定行替换
# xxx
toystoysdf
atoystoy
ssstoystoy
# xxx
# xxx
用sed ‘/^t.*y$/s/$/# xxx/’ zheng.txt 指定行替换
toystoy# xxx
toystoysdf
atoystoy
ssstoystoy
toyfstoy# xxx
toyfdf1stoy# xxx
2、最终行:最后一行指的是输入数据的最后一行,即便是处理多个文件,sed也将他们视为一个长的输入流,且$只能用于最后一个文件的最后一行,他有一个选项,可以使地址分开的应用到每个文件,需要查阅文档
$指最后一行 p表示指定了$最后一行
命令:sed -n ‘$p’ zheng.txt 结果如下:
toyfdf1stoy
3、行编号,可以使用绝对的行编号作为地址
4、范围
可指定行的范围,仅需将地址用逗号隔开
sed -n ‘2,3p’ zheng.txt 此处需要加p指定输出
toystoysdf
atoystoy
sed ‘/^t.*f$/,/^s.*y$/ s/toy/ttt/g’ zheng.txt 仅替换范围内的行
toystoy
tttstttsdf
atttsttt
ssstttsttt
toyfstoy
toyfdf1stoy
sed ‘/foo/,/bar/ s/baz/quux/g’ file从含有foo的行开始,匹配是否有bar的行,再讲结果中有baz的替换
5、否定正则表达式
通过加!在正则表达式后面
sed ‘/^toystoy$/!s/toystoy/ttt/g’ zheng.txt 将所有不以这个开头和结尾的行的toystoy替换
toystoy
tttsdf
attt
sssttt
toyfstoy
toyfdf1stoy
sed ‘/.toystoy./!s/toystoy/ttt/g’ zheng.txt
ttt
tttsdf
attt
sssttt
toyfstoy
toyfdf1stoy

sed改动文本的方式:
正则表达式匹配可以匹配整个表达式的输入文本中最长的,最左边的子字符串。除此之外,匹配的空字符串,则被认为是比完全不匹配的还长(因此,就像我们先前解释的,正则表达式:ab*c匹配文本ac,而b*\则成功的匹配于a c之间的null字符串),完全一致的匹配指的是自最左边开始匹配,针对每一个子模式,由左至右,必须匹配到最长的可能字符串。如果要sed替换由正则表达式匹配的文本,那么确定该正则表达式匹配的字不会太少或太多很重要。
echo abc | sed ‘s/b*/1/’
1abc
echo abc | sed ‘s/b*/1/g’
1a1c1

CUT
这里写图片描述
cut -d : -f 1,5 /etc/passwd
root:root
bin:bin
daemon:daemon
cut -d : -f 6 /etc/passwd
/root
/bin
/sbin
ls -l | cut -c 1-10
total 4
-rw-r–r–

join
sales文件:
1 #业务员数据
2 #业务员量
3 joe 100
4 jane 200
5 chris 300
6 herman 150
quotas文件:
1 #配额
2 #业务员 配额
3 joe 50
4 jane 75
5 herman 80
6 chris 95
jointest.sh
1 #!/bin/sh
2 #删除注释并排序数据文件
3 sed ‘/^#/d’ quotas | sort > quotas.sorted
4 sed ‘/^#/d’ sales | sort > sales.sorted
5
6 join quotas.sorted sales.sorted
7
8 #删除缓存
9 rm sales.sorted quotas.sorted
执行结果:
chris 95 300
herman 80 150
jane 75 200
joe 50 100

awk
awk 读取命令行上所指定的各个文件(若无,则标准输入),一次读取一条记录(行),在针对每一行应用程序所指定的命令。基本框架:pattern {action}。pattern部分可以是任何表达式,但是在单命令行程序里,他通常是由斜杠括起来的。action为任意的awk语句,但是在单命令行程序里,通常是一个直接明了的print语句。pattern和action都能省略但是不能同时省略,省略pattern则会对每一条输入记录执行action,省略action则等同于{print},将显示整条记录。
awk读取输入记录,通常是一些行,然后自动将各个记录切分为字段。awk将每条记录内的字段数目,存储到内建变量NF。
用来从文本文件中提取字段。缺省地,字段分割符是空格,可以使用-F指定其他分割符。
如需字段值,则是搭配$,通常其后会接一个数值常数,也可能是接着一个表达式,不过多半是使用变量名
awk ‘{print $1}’
awk ‘{print $2, $5}’打印第二与第五个字段
awk ‘{print $1, $NF}’打印第1与最后一个字段
awk ‘NF>0 {print $0}’打印非空行,指定pattern与action
awk ‘NF>0’
awk ‘NF>0’ sales
#业务员数据
#业务员量
joe 100
jane 200
chris 300
herman 150
awk ‘{print $1, $NF}’ sales 自动填充了前两行的最后一列
#业务员数据 #业务员数据
#业务员量 #业务员量
joe 100
jane 200
chris 300
herman 150
cat shellTestNew.sh | awk -F, ‘{print $1 “,” $3}’ 这里我们使用,作为字段分割符,同时打印第一个和第三个字段。如果该文件内容如下: Adam Bor, 34, IndiaKerry Miller, 22, USA命令输出结果为:Adam Bor, IndiaKerry Miller。-F会自动设置FS变量,awk自动完成。
每个输出字段是以空格来分割的,即便是输入字段的分割为:。awk输入输出分割字符用法是分开的,必须设置OFS变量,改变输出字段分隔符。方式是在命令里使用-v,可以是任意的字符串。
print如果没有任何参数,相当于print $0,显示整条记录。print会自动提供最后的换行符,print参数间用逗号隔开,否则将连接相邻的所有值
awk -F: -v ‘OFS=**’ ‘{print $1, $5}’ /etc/passwd
root**root
bin**bin
daemon**daemon
awk -F: ‘{print “USER”, $1, “is really”, $5}’ /etc/passwd
USER root is really root
USER bin is really bin
awk -F: ‘{print “USER” 1"isreally" 5}’ /etc/passwd
USERrootis reallyroot
USERbinis reallybin

BEGIN END提供awk程序起始与清除操作,通常写在个别文件里,不在命令行上。语块是可选用的,习惯上分别置于开头和结尾。可以有数个BEGIN END语块,awk会按照他们出现在程序里的顺序执行,所有BEGIN都是起始,所有END都在结尾,BEGIN可以用来设置变量
awk ‘BEGIN {FS=”:”;OFS=”**”}
> {print 1, 5}’ /etc/passwd
root**root
bin**bin
daemon**daemon
> 写入文件并覆盖旧文件
>> 加到文件的尾部,保留旧文件内容

sort :用做排序
这里写图片描述
这里写图片描述
语法:sort [-t 分隔符] [-kn1,n2] [-nru] 这里的n1 < n2
-k指定排序字段,后面接的是一个字段编号,或者是一对数字,有时在-k之后可用空白分割。每个编号后面都可以接一个点号的字符位置,及/或修饰符字幕之一。如下
这里写图片描述
如果仅指定一个字段编号,则排序键值会自该字段的起始处开始,一直继续到记录的结尾(而非字段的结尾)
如果给的是一对用逗号隔开的字段数字,则排序键值将由第一个字段值的起始处开始,结束于第二个字段值的结尾
使用点号字符位置,则比较的开始(一对数字的第一个)或结束(一对数字的第二个)在该字符位置处:
-k2.4,5.6指的是从第二个字段的第四个字符开始比较,一直比到第五个字段的第六个字符
如果一个排序键值的起始正好落在记录的结尾处之后,则排序键值为空,且空的排序键值在排序时将优先于所有非空的键值
当出现多个-k选项时,会先从第一个键值字段开始排序,找出匹配该键值的记录后,在进行第二个键值字段的排序,以此类推
sort -t: -k1,1 /etc/passwd
abrt:x:173:173::/etc/abrt:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
apache:x:48:48:Apache:/var/www:/sbin/nologin
bin:x:1:1:bin:/bin:/sbin/nologin
cloud-agent:x:850:850:Cloud-Agent agent:/opt/cloud-agent/agent:/bin/bash
daemon:x:2:2:daemon:/sbin:/sbin/nologin

sort -t: -k3nr /etc/passwd (第三个字段以整数比较并且倒排)或者sort -t: -k3nr,3 /etc/passwd (从第三个字段开始,结束于第三个字段)
nfsnobody:x:65534:65534:Anonymous NFS User:/var/lib/nfs:/sbin/nologin
cloud-agent:x:850:850:Cloud-Agent agent:/opt/cloud-agent/agent:/bin/bash
saslauth:x:499:76:”Saslauthd user”:/var/empty/saslauth:/sbin/nologin
zabbix:x:498:498:zabbix user:/var/lib/zabbix:/sbin/nologin
logstash:x:497:497:logstash:/opt/logstash:/sbin/nologin
abrt:x:173:173::/etc/abrt:/sbin/nologin

sort -t: -k4nr -k3nr /etc/passwd先按照第四个字段倒排,再按照第三个字段倒排
nfsnobody:x:65534:65534:Anonymous NFS User:/var/lib/nfs:/sbin/nologin
cloud-agent:x:850:850:Cloud-Agent agent:/opt/cloud-agent/agent:/bin/bash
zabbix:x:498:498:zabbix user:/var/lib/zabbix:/sbin/nologin
logstash:x:497:497:logstash:/opt/logstash:/sbin/nologin

-t 分隔符 :作用跟cut的-d一个意思,指定分隔符后,空白是有意义的;如未指定-t表示以空白分隔且记录内开头语结尾的空白都将忽略。因此“ -X- ”如果不指定-t只有一个字段,如果使用-t ’ ’ 则为三个字段,第一个和第三个是空
-n :使用纯数字排序
-r :反向排序
-u :去重复,可以要求sort仅输出唯一的记录,而唯一的是指他们的排序键值字段匹配,即使在记录的其他地方有差异也无所谓。
sort -t: -k4n -u /etc/passwd
-kn1,n2 :由n1区间排序到n2区间,可以只写-kn1,即对n1字段排序

head
head -n n
head -n

tail
tail -n n
tail -n

unset
从shell中删除变量与函数
unset -v var1 var2
unset -f func1删除函数

替换运算符:
varname:wordvarnamenullword {count:-0} count不存在,返回0
varname:wordvarnamenullword {count:=0} count不存在,设置count为0
varname:?messagevarnamenullvarname:message退messageparameternullornotset {count:?”undefined”}count未定义,显示count:undefined并且退出
varname:+wordvarnamenullwordnull {count:+1}count已经定义,返回1,也就是真
以上冒号都是可选的,如果省略冒号,则将每个定义中的“存在且非null”部分改为存在,也就是说,仅用于测试变量是否存在

split :切割文档,常用选项:
-b :依据大小来分割文档,单位为byte
-l :依据行数来分割文档
split -b 100 test.sh
结果:(每个文件存储部分内容)
-rw-r–r– 1 lili staff 100 3 29 23:47 xaa
-rw-r–r– 1 lili staff 100 3 29 23:47 xab
-rw-r–r– 1 lili staff 100 3 29 23:47 xac
-rw-r–r– 1 lili staff 100 3 29 23:47 xad

[ ] :中括号,中间为字符组合,代表中间字符中的任意一个
ll xa[a-c]
-rw-r–r– 1 lili staff 59 3 29 23:51 xaa
-rw-r–r– 1 lili staff 63 3 29 23:51 xab
-rw-r–r– 1 lili staff 70 3 29 23:51 xac

通配符
在bash下,可以使用*来匹配零个或多个字符,而用?匹配一个字符

\ :脱意字符,将后面的特殊符号(例如”*” )还原为普通字符。

查找
/xxx(?xxx) 表示在整篇文档中搜索匹配xxx的字符串, / 表示向下查找, ? 表示向上查找.其中xxx可以是正规表达式,关于正规式就不多说了.一般来说是区分大小写的, 要想不区分大小写, 那得先输入
:set ignorecase 查找到以后, 再输入 n 查找下一个匹配处, 输入 N 反方向查找.
*(#) 当光标停留在某个单词上时, 输入这条命令表示查找与该单词匹配的下(上)一个单词. 同样, 再输入 n 查找下一个匹配处, 输入 N 反方向查找.
g*(g#) 此命令与上条命令相似, 只不过它不完全匹配光标所在处的单词, 而是匹配包含该单词的所有字符串.
gd 本命令查找与光标所在单词相匹配的单词, 并将光标停留在文档的非注释段中第一次出现这个单词的地方.
% 本命令查找与光标所在处相匹配的反括号, 包括 () [] {}
f(F)x 本命令表示在光标所在行进行查找, 查找光标右(左)方第一个x字符.找到后:输入 ; 表示继续往下找输入 , 表示反方向查找

快速移动光标
在 vi 中, 移动光标和编辑是两件事, 正因为区分开来, 所以可以很方便的进行光标定位和编辑. 因此能更快一点移动光标是很有用的.
w(e) 移动光标到下一个单词.
b 移动光标到上一个单词.
0 移动光标到本行最开头.
^ 移动光标到本行最开头的字符处.
$ 移动光标到本行结尾处.
H 移动光标到屏幕的首行.
M 移动光标到屏幕的中间一行.
L 移动光标到屏幕的尾行.
gg 移动光标到文档首行.
G 移动光标到文档尾行.
c-f (即 ctrl 键与 f 键一同按下) 本命令即 page down.
c-b (即 ctrl 键与 b 键一同按下, 后同) 本命令即 page up.
” 此命令相当有用, 它移动光标到上一个标记处, 比如用 gd, * 等查找到某个单词后, 再输入此命令则回到上次停留的位置.
‘. 此命令相当好使, 它移动光标到上一次的修改行.
`. 此命令相当强大, 它移动光标到上一次的修改点.

拷贝, 删除与粘贴
在 vi 中 y 表示拷贝, d 表示删除, p 表示粘贴. 其中拷贝与删除是与光标移动命令结合的, 看几个例子就能够明白了.
yw 表示拷贝从当前光标到光标所在单词结尾的内容.
dw 表示删除从当前光标到光标所在单词结尾的内容.
y0 表示拷贝从当前光标到光标所在行首的内容.
d0 表示删除从当前光标到光标所在行首的内容.
y .d 表示删除从当前光标到光标所在行尾的内容.
yfa 表示拷贝从当前光标到光标后面的第一个a字符之间的内容.
dfa 表示删除从当前光标到光标后面的第一个a字符之间的内容.特殊地:
yy 表示拷贝光标所在行.
dd 表示删除光标所在行.
D 表示删除从当前光标到光标所在行尾的内容.
关于拷贝, 删除和粘贴的复杂用法与寄存器有关, 可以自行查询.

数字与命令
在 vi 中数字与命令结合往往表示重复进行此命令, 若在扩展模式的开头出现则表示行号定位. 如:
5fx 表示查找光标后第 5 个 x 字符.
5w(e) 移动光标到下五个单词.
5yy 表示拷贝光标以下 5 行.
5dd 表示删除光标以下 5 行.
y2fa 表示拷贝从当前光标到光标后面的第二个a字符之间的内容.
:12,24y 表示拷贝第12行到第24行之间的内容.
:12,y 表示拷贝第12行到光标所在行之间的内容.
:,24y 表示拷贝光标所在行到第24行之间的内容. 删除类似.

快速输入字符
在 vi 中, 不要求你输入每一个字符, 可以有很多种方法快速输入一些字符.
使用 linux/unix 的同学一定有一个经验, 在命令行下输入命令时敲入头几个字符再按TAB 系统就会自动将剩下的字符补齐, 假如有多个匹配则会打印出来. 这就是著名的命令补齐(其实windows中也有文件名补齐功能). vi 中有许多的字符串补齐命令, 非常方便.
c-p(c-n) 在编辑模式中, 输入几个字符后再输入此命令则 vi 开始向上(下)搜
索开头与其匹配的单词并补齐, 不断输入此命令则循环查找. 此命令会在所有在这个 vim 程序中打开的文件中进行匹配.
c-x-l 在编辑模式中, 此命令快速补齐整行内容, 但是仅在本窗口中出现的文档中进行匹配.
c-x-f 在编辑模式中, 这个命令表示补齐文件名. 如输入:
/usr/local/tom 后再输入此命令则它会自动匹配出:
/usr/local/tomcat/
abbr 即缩写. 这是一个宏操作, 可以在编辑模式中用一个缩写代替另一个字符串. 比如编写java文件的常常输入 System.out.println, 这很是麻烦, 所以应该用缩写来减少敲字. 可以这么做:
:abbr sprt System.out.println 以后在输入sprt后再输入其他非字母符号, 它就会自动扩展为System.
out.println

替换
替换是 vi 的强项, 因为可以用正规表达式来匹配字符串.以下提供几个例子.
:s/aa/bb/g 将光标所在行出现的所有包含 aa 的字符串中的 aa 替换为 bb
:%s/aa/bb/g 将文档中出现的所有包含 aa 的字符串中的 aa 替换为 bb
:12,23s/aa/bb/g 将从12行到23行中出现的所有包含 aa 的字符串中的 aa 替换为 bb
:12,23s/^/#/ 将从12行到23行的行首加入 # 字符
:%s= * ==:g/\s /d 将所有不包含字符(空格也不包含)的空行删除.

正则表达式
这里写图片描述
这里写图片描述
zheng.txt:
toystoy
toystoysdf
atoystoy
ssstoystoy
toyfstoy
toyfdf1stoy

grep命令及结果:
cat zheng.txt | grep toystoy
toystoy
toystoysdf
atoystoy
ssstoystoy

cat zheng.txt | grep ^toystoy
toystoy
toystoysdf

cat zheng.txt | grep toystoy$
toystoy
atoystoy
ssstoystoy

cat zheng.txt | grep ^toystoy$
toystoy

cat zheng.txt | grep toy.toy
toystoy
toystoysdf
atoystoy
ssstoystoy

cat zheng.txt | grep toy.toy$
toystoy
atoystoy
ssstoystoy

cat zheng.txt | grep ^toy.toy$
toystoy

cat zheng.txt | grep toy.*toy
toystoy
toystoysdf
atoystoy
ssstoystoy
toyfstoy
toyfdf1stoy

cat zheng.txt | grep toy.*toy$
toystoy
atoystoy
ssstoystoy
toyfstoy
toyfdf1stoy

cat zheng.txt | grep ^toy.*toy$
toystoy
toyfstoy
toyfdf1stoy

方括号表达式,最简单的就是将字符放到方括号里面。方括号表达式里面,放在首字母前面的^标识取反,即,不能使方括号中的任意字符,大小写敏感,即方括号中小写,大写就满足取反条件。
方括号表达式可以包括字符范围[0-9a-fA-F]

*标识匹配0个或多个前面的单个字符,ab*c标识,匹配1个a,0或多个b,以及啊a c,注意匹配0或多个必须是同样的字符,不能是其他的字符
+与*类似,不过前置正则表达式要匹配的文本至少得出现一次,不能是0个

区间表达式,指定匹配次数,接在单个字符正则表达式后面,控制字符重复几次即为成功。
{n}前置正则表达式所得结果重现n次
{n,}前置正则表达式所得结果至少重现n次
{n,m}前置正则表达式所得结果重现n-m次

^abcd | efgh abcdefghabcd|efgh 标识找abcd或者efgh

shell脚本:

#!/bin/sh
#对变量赋值

a=”Hello World”
echo ‘A is: ’
echo “${a}”;

num=2
num=2
echo “this is the ${num}nd number”;

read a
echo $a

流程控制
“if” 表达式 如果条件为真则执行then后面的部分:
if ….; then
  ….
elif ….; then
  ….
else
  ….
fi
通常用” [ ] “来表示条件测试。注意这里的空格很重要。要确保方括号的空格。
[ -f “somefile” ] :判断是否是一个文件
[ -x “/bin/ls” ] :判断/bin/ls是否存在并有可执行权限
[ -n “ var"] var变量是否有值
[ “ a"=" b” ] :判断 a b是否相等
if [ “ SHELL=/bin/bash];then echoyourloginshellisthebash(bourneagainshell)else echoyourloginshellisnotbashbut SHELL”
fi
变量$SHELL包含了登录shell的名称,我们和/bin/bash进行了比较

快捷操作符
[ -f “/etc/shadow” ] && echo “This computer uses shadow passwors”
  这里 && 就是一个快捷操作符,如果左边的表达式为真则执行右边的语句。您也可以认为是逻辑运算中的与操作。上例中表示如果/etc/shadow文件存在则打印” This computer uses shadow passwors”。

case表达式可以用来匹配一个给定的字符串,而不是数字。
case … in
…) do something here ;;
esac
echo “case例子”
case $1 in
start | begin)
echo “start”
;;
stop | end)
echo “end”
;;
*)
echo “ingnore”
;;
esac

file lf.gz
  这将返回:
lf.gz: gzip compressed data, deflated, original filename,
last modified: Mon Aug 27 23:09:18 2001, os: Unix
 我们利用这一点写了一个叫做smartzip的脚本,该脚本可以自动解压bzip2, gzip 和zip 类型的压缩文件:
#!/bin/sh
ftype=file "$1"
case “ ftypein 1: Zip archive”*)
  unzip “ 1;; 1: gzip compressed”*)
  gunzip “ 1;; 1: bzip2 compressed”*)
  bunzip2 “ 1;;)errorFile 1 can not be uncompressed with smartzip”;;
esac
  
select 表达式是一种bash的扩展应用,尤其擅长于交互式使用。用户可以从一组不同的值中进行选择。
select var in … ; do
 break
done
…. now varcanbeused.selectchinstartendexitdocase ch in
“start”)
echo “start something”
;;
“end”)
echo “end something”
;;
“exit”)

echo “exit”
break
;;
*)
echo “ignore”
;;
esac
done
loop表达式:
while …; do
….
done
  while-loop 将运行直到表达式测试为真。关键字”break” 用来跳出循环。而关键字”continue”用来不执行余下的部分而直接跳到下一个循环。
echo “while循环例子1”
i=10
while [[ i -gt 5 ]]# 注意空格  
do  
echo
i
((i–))
done

echo “while循环例子2”
while read line
do
echo $line
done < hosts

  for-loop表达式查看一个字符串列表 (字符串用空格分隔) 然后将其赋给一个变量:
for var in ….; do
 ….
done
#!/bin/sh
for var in A B C;
do
echo “var is ${var}”
done

echo “for循环例子1”
for ((i=1;i<10;i++))
do
echo $i
done

echo “for循环例子2”
for i in 1 2 3 4
do
echo $i
done

echo “for循环例子3”
for file in doif[f file ]
then
echo “Info: fileexistelseechoError: file not exist”
fi
done

showrpm,其功能是打印一些RPM包的统计信息:
#!/bin/sh
# list a content summary of a number of RPM packages
# USAGE: showrpm rpmfile1 rpmfile2 …
# EXAMPLE: showrpm /cdrom/RedHat/RPMS/*.rpm
for rpmpackage in ;do if[r rpmpackage” ];then
  echo “=============== rpmpackage==============  rpmqip rpmpackage
 else
  echo “ERROR: cannot read file rpmpackage”  
 fi  
done  
 #!/bin/sh   
 # list a content summary of a number of RPM packages   
 # USAGE: showrpm rpmfile1 rpmfile2 …   
 # EXAMPLE: showrpm /cdrom/RedHat/RPMS/*.rpm   
for rpmpackage in
*; do
 if [ -r “ rpmpackage];then  echo=============== rpmpackage ==============”
  rpm -qi -p rpmpackage else  echoERROR:cannotreadfile rpmpackage”
 fi
done
  这里出现了第二个特殊的变量 showrpmopenssh.rpmw3m.rpmwebgrep.rpm   * 包含了 3 个字符串,即openssh.rpm, w3m.rpm and webgrep.rpm.

函数调用
echo “函数文件调用”
#调用函数文件,点和demo_call中间有空格
. demo_call.sh
callFunction lili

# 用unset functionname 取消载入
#unset callFunction
# 因为已经取消载入,所以会出错
#callFunction lili

demo_call.sh
#!/bin/bash
function callFunction(){
echo “call function $1 1”
return 1
}

echo “return”
funWithReturn(){
echo “input first number”
read num1
echo “input second number”
read num2
echo “the two numbers are num1and num2”
return (( num1+$num2))
}

funWithReturn
# 函数返回值在调用该函数后通过 ?echosumofthetwonumbersare ?”

多文件编辑
在一个 vim 程序中打开很多文件进行编辑是挺方便的.
:sp(:vsp) 文件名 vim 将分割出一个横(纵)向窗口, 并在该窗口中打开新文件.从 vim6.0 开始, 文件名可以是一个目录的名称, 这样, vim 会
把该目录打开并显示文件列表, 在文件名上按回车则在本窗口打开该文件, 若输入 O 则在新窗口中打开该文件, 输入 ? 可以看到帮助信息.
:e 文件名 vim 将在原窗口中打开新的文件, 若旧文件编辑过, 会要求保存.
c-w-w vim 分割了好几个窗口怎么办? 输入此命令可以将光标循环定位到各个窗口之中.
:ls 此命令查看本 vim 程序已经打开了多少个文件, 在屏幕的最下方会显示出如下数据:
1 %a “usevim.html” 行 162
2 # “xxxxxx.html” 行 0
其中:
1 表示打开的文件序号, 这个序号很有用处.
%a 表示文件代号, % 表示当前编辑的文件,
# 表示上次编辑的文件
“usevim.html” 表示文件名. 行 162 表示光标位置.
:b 序号(代号) 此命令将指定序号(代号)的文件在本窗口打开, 其中的序号(代号)就是用 :ls 命令看到的.
:set diff 此命令用于比较两个文件, 可以用
:vsp filename 命令打开另一个文件, 然后在每个文件窗口中输入此命令,就能看到效果了.

宏替换
vi 不仅可以用 abbr 来替换文字, 也可以进行命令的宏定义. 有些命令输起来很费劲,
因此我把它们定义到 - 上, 这样就很方便了.这些配置可以预先写到 ~/.vimrc (windows 下为 VIM/vimrc),.:nmap:nohls:nmapw:imap:nmap: == 删除所有行尾多余的空格.
:imap 同上
:java 中: (注, 这里为什么说 java 中, 因为以下定义对其他文件格式不起作用, 下文会说到如何实现这一点)
:nmap :comp javac:mak -d . %此命令用 javac 编译 java 文件, 它会自动将光标定位到出错点. 不过这需要定义一个 javac.vim 文件在 $VIM/compiler 下, 在 javac.vim 里面只有两行字:
setlocal makeprg=javac
setlocal errorformat=%A%f:%l:\ %m,%-Z%p^,%-C%.%#
:nmap :comp ant:mak
此命令用 ant 编译 java 文件, 它会自动将光标定位到出错点. 一般来说, 安装vim 后已经有了compiler/ant.vim文件, 因此这个命令可以直接使用. 但是需要在当前目录下有 build.xml 文件, 当然还必须安装 ant 才行.
:nmap :cl 此命令用于查看所有的编译错误.
:imap
:nmap :cc 此命令用于查看当前的编译错误.
:imap
:nmap :cn 此命令用于跳到下一个出错位置.
:imap
:nmap :cp 此命令用于跳到上一个出错位置.
:imap
:nmap :JavaBrowser
此命令用于在窗口左部分割出一个新窗口, 里面的内容是 java 的资源树, 包括本文件中出现的类, 类的成员变量及成员方法, 就好像 JCreator 表现的那样.在这个窗口中输入 ? 会看到帮助. 嘿嘿, 很好用, 不过需要 ctags 支持.
:imap

TAB
TAB 就是制表符, 单独拿出来做一节是因为这个东西确实很有用.
<< 输入此命令则光标所在行向左移动一个 tab.

输入此命令则光标所在行向右移动一个 tab.
5>> 输入此命令则光标后 5 行向右移动一个 tab.
:12,24> 此命令将12行到14行的数据都向右移动一个 tab.
:12,24>> 此命令将12行到14行的数据都向右移动两个 tab.
那么如何定义 tab 的大小呢? 有人愿意使用 8 个空格位, 有人用4个, 有的用2个.有的人希望 tab 完全用空格代替, 也有的人希望 tab 就是 tab. 没关系, vim 能帮助你.以下的设置一般也都先写入配置文件中, 免得老敲.
:set shiftwidth=4 设置自动缩进 4 个空格, 当然要设自动缩进先.
:set sts=4 即设置 softtabstop 为 4. 输入 tab 后就跳了 4 格.
:set tabstop=4 实际的 tab 即为 4 个空格, 而不是缺省的 8 个.
:set expandtab 在输入 tab 后, vim 用恰当的空格来填充这个 tab.

autocmd
这个命令十分的强大, 可以用这个命令实现对不同的文件格式应用不同的配置; 可以在新建文件时自动添加上版权声明等等. 这些命令一般定义在 ~/.vimrc 这样的配置文件里面. 由于他很强大, 所以我不能给出很具体的说明, 只能举几个例子, 详细的请看帮助.
:autocmd! 删除所有之前的自动命令.
autocmd FileType java source ~/.vim/files/java.vim
autocmd FileType java source ~/.vim/files/jcommenter.vim
以上两条命令让我在打开 java 文件时才应用后面提到的两个配置文件.
autocmd BufNewFile *.java 0r ~/.vim/files/skeletons/java.skel
以上这条命令让我在新建 java 文件时自动加入 java.skel 文件的内容.
autocmd BufNewFile *.java normal gnp
以上这条命令让我在新建 java 文件时自动运行 gnp 命令, 这个命令进行一些特殊化处理, 比如将新 java 文件中的 date 替换成今天的日期什么的.

常用脚本
在 vim.sf.net 你可以发现很多脚本(script), 这些脚本常常有让你意想不到的作用.
我常用的有:
jcommenter.vim 自动加入 javadoc 风格的注释.
JBrowser.vim 类资源浏览. C, C++ 等可以用 Tlist
还有许多有用的, 比如 checkstyle.vim 可以检验你的编程风格, jad.vim 可以直接反编译 .class 文件等等.

常用配置
在~/.vimrc 配置文件中你常常需要一些个性化配置. 比如上面写的一些宏定义, 一些
autocmd 定义等等. 比如:
set suffixes=.bak,~,.o,.h,.info,.swp,.aux,.bbl,.blg,.dvi,.lof,.log,.lot,.ps,.toc
这样在vim中打开文件时, 按 tab 键补齐文件名时它会忽略上述文件.
set nu 显示行号
set ai 设置自动缩进
map Y y$ 让 Y 和 D 一样, 要不然 Y 的本意和 yy 一样.

其他
还有许多有意思的命令, 记录在这里免得忘记.
. 重复上次编辑命令.
:g/^/exec “s/^/”.strpart(line(“.”).” “, 0, 4) 在行首插入行号
:runtime! syntax/2html.vim 转换 txt 成 html, 会按照你的
颜色配置来转
支持Java:
对标签跳跃的支持
标签是Java的标识符,它们可以是包装名、类名、方法名,或者是字段名。在你的代码里创建一个所有标签的大型索引,能够让你使用单个按键就跳跃到任何类、方法或者字段的定义上。这些索引文件都是使用ctags程序创建的,后者在vim的发行版里都有。Ctags会获取Java源文件或者包含有Java源代码的目录的列表,从中提取标识符的信息,再生成所vi需要的用于跳跃到标签的排序索引。下面一行代码是ctags调用的一个例子,只要JAVA_HOME变量被正确地定义,它会生成一个包含有项目源代码里所有标识符的标签文件,Sun核心库源代码也是如此:
ctags -f ~/.tags -R ~/myprojects/src $JAVA_HOME/src
一旦标签索引创建好了,你所需要做的只是告诉vi要在哪里找到它。这一步是通过将set
tags=~/.tags添加到你的~/.vimrc文件里实现的。有了可用的标签索引文件,而且vi也知道了要到哪里去找到它,
你现在就可以通过按[CTRL]]来跳跃到任何标识符上了。尽管这对于跳跃到你已经定义的方法、类和你自己编写的字段上很有用,但是如果你将Java核心类库加到你的标签索引里将会更加有用。现在,只用简单地对任何核心类库的类或者方法按[Ctrl] ],你就会跳跃到它完全使用javadoc所编写成的定义。.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值