您的位置:首页 > 运维架构 > Shell

linux之vim编辑器与shell编程基础

2015-10-21 15:44 519 查看

Vim学习

Vim的普通模式下按Ctrl+z会把当前打开的文件放入后台运行,如果需要恢复到前台来,需要先在shell的命令模式下用jobs命令查看当前环境下所有任务的编号,在用fg %N恢复到前台来,N是对应的后台运行编号。

 

dw是删除一个单词(或者daw),dnw删除n个单词。

nx是删除那个字符,ndd是删除n行。

命令模式下:set nu 是显示行号。

nG(n shift+g)将游标移动到第n行。gg移动到第一行,G(shift+g)移动到最后一行。

命令
说明
w
到下一个单词的开头
e
到下一个单词的结尾
b
到前一个单词的开头
ge
到前一个单词的结尾
0或^
到行头
$
到行尾
f<字母>
向后搜索<字母>并跳转到第一个匹配的位置(非常实用)
F<字母>
向前搜索<字母>并跳转到第一个匹配的位置
t<字母>
向后搜索<字母>并跳转到第一个匹配位置之前的一个字母(不常用)
T<字母>
向前搜索<字母>并跳转到第一个匹配位置之后的一个字母(不常用)
Ps:搜索字符并跳转只能在当前行内有效,不能跳转到下一行。

 

·        普通模式中使用y复制

o   普通模式中,yy复制游标所在的整行(3yy表示复制3行)
o   普通模式中,y^ 复制至行首,或y0。不含光标所在处字符。
o   普通模式中,y$ 复制至行尾。含光所在处字符。
o   普通模式中,yw 复制一个单词。
o   普通模式中,y2w 复制两个单词。
o   普通模式中,yG 复制至文本末。
o   普通模式中,y1G 复制至文本开头。

·        普通模式中使用p粘贴

o   普通模式中,p(小写)代表粘贴至光标后(下)
o   普通模式中,P(大写)代表粘贴至光标前(上)

替换和撤销(Undo)命令
替换和Undo命令都是针对普通模式下的操作
命令
说明
r+<待替换字母>
将游标所在字母替换为指定字母
R
连续替换,直到按下Esc
cc
替换整行,即删除游标所在行,并进入插入模式
cw
替换一个单词,即删除一个单词,并进入插入模式
C(大写)
替换游标以后至行末
~
反转游标所在字母大小写
u{n}
撤销一次或n次操作
U(大写)
撤销当前行的所有修改
Ctrl+r
redo,即撤销undo的操作
 

普通模式下直接输入>>或<<,相当于在光标处之前的地方加一个Tab(又叫跳格符或制表符),多用于在代码文件中调整格式用。

我们可以自己调整Tab的宽度,只要在命令模式下输入:set shiftwidth=10 ,将一个Tab的距离设置成10个字符的宽度,但只是改>>的宽度,并不能改编辑模式下的Tab宽度,编辑模式下的一个Tab通常默认的是8个字符宽。

 

关于查找

普通模式下输入
/
然后键入需要查找的字符串按回车后就会进行查找。
/
功能相同,只不过
是向上而
/
是向下查找。进入查找之后,输入
n
N
可以继续查找 
n
表示继续查找,
N
反向查找。

普通模式下输入\*寻找游标所在处的单词

普通模式下输入\#同上,但 \*
是向前(上)找,#则是向后(下)找

普通模式下输入g\*同\*
,但部分符合该单词即可

普通模式下输入g\#同\#
,但部分符合该单词即可

 

恢复文档与加密文档
如果因为断电等原因造成文档没有保存,可以采用恢复方式,vim -r进入文档后,输入:ewcover 1.txt来恢复

 

$ vim -x file1

如果文件之前没有密码,则会需要输入您的密码再输入一次确认密码,这样在下一次打开时,vim就会要求你输入密码。
如果需要解除文件密码,则输入正确密码进入文件,在命令模式里输入:set key=
这样就没有密码了。还有一个更简单的直接:X 一直按回车就好了,也就是给空密码。
可视模式
在普通模式下输入v(小写),进入字符选择模式,就可以移动光标,光标走过的地方就会选取。再次按下v会后就会取消选取。

在普通模式下输入Shift+v(小写),进入行选择模式,按下V之后就会把整行选取,您可以上下移动光标选更多的行,同样,再按一次Shift+v就可以取消选取。

在普通模式下输入 Ctrl+v(小写),这是区域选择模式,可以进行矩形区域选择,再按一次Ctrl+v取消选取。

在普通模式下输入d删除选取区域内容

在普通模式下输入y复制选取区域内容

 

Shell编程

变量相关

env是查看环境变量,而set是查看当前所有变量(包括用户自定义的变量)。自定义变量中用的最多、看的最多的其实是SP1变量,我们可以用set查看一下,env是不能看到的,因为它不是环境变量。SP1变量保存的就是用户命令提示符。

 

Locale命令是查看当前系统语系,主要看LANG和LC_ALL的变量。

LANG:定义系统主语系的变量

LC_ALL:定义整体语系变量

对于这两个变量可以粗略的理解成LANG是当前的语系(临时的),而LC_ALL是总体的语系,重启后当前语系将恢复成LC_ALL的值。

 

$?,表示上一个命令执行的结果,0为真(正常执行),非零为假(执行失败)。

$n,n是正整数,$0是代表命令本身,$1-$9分别代表参数1到参数9,例:./hello.shabc 11 22,./hello.sh是命令本身(执行一个hello.sh的脚本)为$0,后面的abc是第一个参数$1,11和12分别是第二和第三个参数,即$2和$3。在实际的shell程序里面,可以直接用$n的值。如果参数大于10个需要大括号,如${10}。

$*,代表所有参数,把所有参数看为一个整体。如上面的例子里面$*的值为abc 11 22。

$@,也代表所有参数,但和$*不同的是,在使用时是区别开的,即一个一个使用。

$#,代表的是参数个数。

例子:

#/bin/bash

#this file is plus.sh

Sum=(($1 + $2))

echo $Sum

echo $*

echo $@

echo $#

执行这个脚本:./plus.sh11 22

结果:

33

11 22

11 22

2

 

例2:

#!/bin/bash

#this file is for.sh

for i in "$*"

        do

                echo $i

        done

 

for j in "$@"

        do

                echo $j

        done           

执行脚本:./for.sh1 2 3 4

结果:

1 2 3 4

1

2

3

4

 

read命令(非常实用的命令):

参数:-p “提示信息”  ------在读入一个值之前,输出一些提示信息

-t 秒数  -------指定等待用户输入的最大时限

-n 数字  -------指定读入最大字符数

-s  --------隐藏用户输入,类似用户登录时输入密码的效果 

 

测试语句
1、        按文件类型进行判断

-b        判断文件是否存在,并且是否为块设备文件

-c        判断文件是否存在,并且是否为字符设备文件

-d        判断文件是否存在,并且是否为目录文件(是目录文件为真)

-e        判断文件是否存在(存在为真)

-f         判断文件是否存在,并且是否为普通文件

-L        判断文件是否存在,并且是否为链接文件

-p        判断文件是否存在,并且是否为管道文件

-s        判断文件是否存在,并且是否为非空(是非空为真)

-S        判断文件是否存在,并且是否为套接字文件

 

2、        按照文件权限判断

-r         判断文件是否存在,并且拥有读权限

-w       判断文件是否存在,并且拥有写权限

-x        判断文件是否存在,并且拥有执行权限

-u        判断文件是否存在,并且拥有SUID权限

-g        判断文件是否存在,并且拥有SGID权限

-k        判断文件是否存在,并且拥有SBit权限

 

3、        两个文件之间进行比较

文件1 -nt
文件2        
判断文件1的修改时间是否比文件2的新

文件1 -ot
文件2        
判断文件1修改该时间是否比文件2的旧

文件1 -ef 文件2          判断文件1是否和文件2的inode号一致,可以理解为两个文件是否为同一个文件。通常用于判断硬链接。

 

4、        两个整数之间比较

整数1 -eq
整数2        
判断两数是否相等

整数1 -ne
整数2        
判断两数是否不相等

整数1 -gt
整数2         
判断整数1是否大于整数2

整数1 -lt
整数2          
判断整数1是否小于整数2

整数1 -ge
整数2        
判断整数1是否大于等于整数2

整数1 -le
整数2         
判断整数1是否小于等于整数2

eq是equal的缩写 
ne是 not equal的缩写
 gt是great
than的缩写  lt是less
than的缩写  ge是great thanor equal to的缩写
 le是less than
equal to的缩写

 

5、        字符串的判断

-z 字符串          
判断字符串是否为空

-n 字符串          
判断字符串是否为非空

字串1 == 字串2          判断两个字串是否相等

字串1 =! 字串2           判断两个字串是否不等

 

6、        多重条件判断

判断1 -a 判断2           逻辑与,两个都成立结果为真

判断1 -o 判断2           逻辑或,有一个为真,即结果为真

!判断          逻辑非,将判断结果取反

 

两种判断格式

l  test -e /root/install.log

l  [ -e /root/install.log ] 推荐使用这种

 

if语句
if [ 条件判断式 ];then

      条件成立执行的语句

      else

      不成立时执行的语句

fi

或者

if [ 条件判断式 ]

      then

      条件成立时执行的语句

      else

      条件不成立时执行的语句

Fi

 

case语句
基本格式:

case $变量名 in

      “值1”)

           如果变量的值等于值1,则执行程序1

           ;;

      “值2”)

           如果变量的值等于值2,则执行程序2

           ;;

      *)

           如果变量的值都不是以上的值,则执行此程序代码

           ;;

esac

 

for语句
语法一、

for 变量 in值1
值2
值3…..

      do

           程序

      done

语法二、

for(( 初始值;循环控制条件;变量变化
))

      do

           程序

      done

语法二类似c语言的for循环

 

while循环和until循环
while [ 条件判断式 ]

      do

           程序

      done

只要条件判断式成立,就开始循环。

通常在程序代码里,应该有可以退出循环的控制语句。

 

Until循环和while循环相反,只要条件判断式不成立就开始循环。一旦循环条件成立时,则循环终止。

 

 

 

Linux下$()与${}、$(())详解

一、关于$()

其实$()与``(反勾号)的作用相同,都是用来做命令替换用的,也就是用来重组命令行的。里面包含的必须是一个命令语句。

在实际使用中,command line里面出现$(),会先执行$()里面的命令语句。比如:

echo today is $(date)!我们知道date命令是打印当前的时间,那么先执行date命令,在通过echo命令将整个句子结果打印到标准输出,结果是:today is Sun Oct 1820:24:31 CST 2015!

当然整句命令可以替换成:echotoday is `date`!结果完全一样。

 

$()与``比较

优点:$()可以很好的与’’(单引号)区别开来,实际使用直观可读性好。

缺点:可移植性没有``好,``基本可用在其他所有shell中。

 

二、关于${}

先看例子:

先定义一个变量A=he,现在想要输出hello,我们可以echo $Allo,这是你会发现输出的是空,原因就是shell会把你的变量识别成$Allo而不是$A+llo,而$Allo是一个没有赋值的变量,当然会输出空。现在我们改一下echo
${A}llo,此时得到hello正确结果。显然${}是变量的定界符,标明变量名的长度界限,增强可读性。其实我们平常写的$A只是${A}的简写形式,在shell script里面,应尽量避免用简写形式,这样可以大大减少出错。

 

${}如果仅仅只是起到定界符的作用,那就太小看它了,以下是它的一些特殊并常用的用法示例:

假设我们定义了一个变量为:

file=/dir1/dir2/dir3/my.file.txt
我们可以用 ${ }
分别替换获得不同的值:
${file#*/}拿掉第一条 /
及其左边的字符串:dir1/dir2/dir3/my.file.txt
${file##*/}拿掉最后一条 /
及其左边的字符串:my.file.txt
${file#*.}拿掉第一个.  及其左边的字符串:file.txt
${file##*.}拿掉最后一个.  及其左边的字符串:txt
${file%/*}拿掉最后条 /
及其右边的字符串:/dir1/dir2/dir3
${file%%/*}拿掉第一条 /
及其右边的字符串:(空值)
${file%.*}拿掉最后一个.  及其右边的字符串:/dir1/dir2/dir3/my.file
${file%%.*}拿掉第一个.  及其右边的字符串:/dir1/dir2/dir3/my
记忆的方法为:

[list]# 是去掉左边(在鉴盘上 #
在 $
之左边)

% 是去掉右边(在鉴盘上 %
在 $
之右边)
单一符号是最小匹配﹔两个符号是最大匹配。[/list]
${file:0:5}提取最左边的 5
个字节:/dir1
${file:5:5}提取第 5
个字节右边的连续 5
个字节:/dir2

我们也可以对变量值里的字符串作替换:
${file/dir/path}将第一个 dir
提换为 path:/path1/dir2/dir3/my.file.txt
${file//dir/path}将全部 dir
提换为 path:/path1/path2/path3/my.file.txt

利用 ${ }
还可针对不同的变量状态赋值(没设定、空值、非空值):

${file-my.file.txt} 假如 $file
没有设定,则使用my.file.txt
作传回值。(空值及非空值时不作处理)
${file:-my.file.txt} 假如 $file
没有设定或为空值,则使用my.file.txt
作传回值。 (非空值时不作处理)
${file+my.file.txt} 假如 $file
设为空值或非空值,均使用my.file.txt
作传回值。(没设定时不作处理)
${file:+my.file.txt} 若 $file
为非空值,则使用my.file.txt
作传回值。 (没设定及空值时不作处理)
${file=my.file.txt} 若 $file
没设定,则使用my.file.txt
作传回值,同时将 $file
赋值为my.file.txt
。 (空值及非空值时不作处理)
${file:=my.file.txt} 若 $file
没设定或为空值,则使用my.file.txt
作传回值,同时将 $file
赋值为 my.file.txt。 (非空值时不作处理)
${file?my.file.txt} 若 $file
没设定,则将my.file.txt
输出至 STDERR。 (空值及非空值时不作处理)
${file:?my.file.txt} 若 $file
没设定或为空值,则将my.file.txt
输出至 STDERR。 (非空值时不作处理)

tips:
以上的理解在于,
你一定要分清楚 unset
与 null
及 non-null这三种赋值状态.
一般而言, :
与 null
有关,
若不带 :
的话, null
不受影响,
若带 :
则连 null
也受影响.
还有哦,${#var}
可计算出变量值的长度:
${#file} 可得到 27
,因为/dir1/dir2/dir3/my.file.txt
刚好是27
个字节...

接下来,再为大家介稍一下bash
的组数(array)处理方法。
一般而言,A="ab c def"
这样的变量只是将 $A
替换为一个单一的字符串,
但是改为 A=(a b cdef)
,则是将 $A
定义为组数...

bash 的组数替换方法可参考如下方法:
${A[@]} 或 ${A[*]}
可得到 a b cdef (全部组数)
${A[0]} 可得到 a (第一个组数),${A[1]}
则为第二个组数...
${#A[@]} 或 ${#A[*]}可得到 4 (全部组数数量)
${#A[0]} 可得到 1 (即第一个组数(a)的长度),${#A[3]}
可得到 3 (第四个组数(def)的长度)

A[3]=xyz 则是将第四个组数重新定义为xyz ...

诸如此类的....

 

二、关于$(())

好了,最后为大家介绍 $(( ))
的用途吧:它是用来作整数运算的。

在 bash 中,$(( )) 的整数运算符号大致有这些:

+ - * / :分别为 "加、减、乘、除"。

% :余数运算

& | ^ !:分别为 "AND、OR、XOR、NOT" 运算。

例:

$ a=5; b=7; c=2

$ echo $(( a+b*c ))

19

$ echo $(( (a+b)/c ))

6

$ echo $(( (a*b)%c))

1


在 $(( )) 中的变量名称,可于其前面加 $ 符号来替换,也可以不用,如:

$(( $a + $b * $c)) 也可得到 19 的结果

此外,$(( )) 还可作不同进位(如二进制、八进位、十六进制)作运算呢,只是,输出结果皆为十进制而已:

echo $((16#2a)) 结果为 42 (16进位转十进制)

以一个实用的例子来看看吧:

假如当前的  umask是 022 ,那么新建文件的权限即为:

$ umask 022

$ echo "obase=8;$(( 8#666 & (8#777 ^ 8#$(umask)) ))" | bc

644


事实上,单纯用 (( )) 也可重定义变量值,或作 testing:

a=5; ((a++)) 可将 $a 重定义为 6

a=5; ((a--)) 则为 a=4

a=5; b=7; ((a < b)) 会得到  0 (true) 的返回值。

常见的用于 (( )) 的测试符号有如下这些:

[list]<:小于

>:大于

<=:小于或等于

>=:大于或等于

==:等于

!=:不等于[/list]

不过,使用 (( )) 作整数测试时,请不要跟 [ ] 的整数测试搞混乱了。

参考文献:
http://man.linuxde.net/
<<高级bash shell脚本编程指南>>

慕课网tony的教学系列视频

 最后更新:

10.21
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息