Linux小技巧收集[增长]

作者:Ajian 发布时间:January 16, 2009 分类:杂记摘要

前言:因为用Linux的时间越来越长,所需要做的事也越来越多,效率成了我必需突破的瓶颈。在此总结一下这段时间用过的一些好的Linux技巧。以后时常补充这样自己要用的时候就很方便了。

[文本处理]

1、查看某文件的一部分

如果你只想看文件的前 5 行,可以使用 head 命令,

如:head -5 /etc/passwd

如果你想查看文件的后 10 行,可以使用 tail 命令,

如:tail -10 /etc/passwd

查看文件中间一段,可以使用 sed 命令

如:sed –n '5,10p' /etc/passwd 这样你就可以只查看文件的第 5 行到第 10 行

2、将 file.txt 里的123改为 456

方法 1

sed 's/123/456/g' file.txt > file.txt.new 修改的保存到其它文件

sed -i 's/123/456/g' file.txt 直接修改原文件

方法 2

vi file.txt

输入命令:

:%s/123/456/g

注意:如果替换的文件有特殊符号如/就要用\来取消。

例:sed -i 's/\/usr\/local\/apache2\/htdocs/\/var\/www\/html/g' /usr/local/apache2/conf/httpd.conf

如果只是下原有的行后添加就用&

例:sed -i 's/DirectoryIndex index.html index.html.var/& index.htm index.php /g' /usr/local/apache2/conf/httpd.conf

3、echo 典型应用

echo "abcdefg" | perl -lne '{$a = reverse($_); print $a;}' 把一个字符串翻转

echo bottle|rev 把一个字符串翻转

4、过滤掉#号打头的行,和所有的空行(对于查看配置文档很有用)

awk '/^[^#]/&&/^[^$]/' filename > new.file

5、查看文件的第一列

如:查看/etc/passwd的第一列 ,取出所有的用户名

awk -F : '{print $1}' /etc/passwd > passwd.txt

6、更改字符集

网站因为迁移改变了原有的字符集,导致前台看到乱码。如果是少数的几个页可以直接拿到本地用Editplus或者UltraEdit进行另存为时选择字符编码。现在有一个不用拿到本地的方法,在Linux机器上就能进行。

conv -f <native encoding> -t <wanted encoding> <filename> -o <newfilename>

如:将GB2312转为UTF-8 注意:转成的必须是新的文件名,不然会出错。

/usr/bin/iconv –f GB2312 –t UTF-8 sourcefile > targetfile

7、dos2unix批量转

我从Windows系统SVN Checkout的文件都是Dos的格式了 Copy到Linux下后不能使用 批量转换

1、find -type f | xargs dos2unix -o

2、#!/bin/sh

for i in `find -type f`

do

dos2unix $i

done

8、在写Shell程序要注释多行,不想删除时 或者在配置文件中想注释多行时,Shell没有提供多行注释的命令。但有些其它的小技巧。

vi .

:line1,lineN s/^/#/g

Vim

在vim里下面的快捷键命令就达到了为m-n行添加注释的效果

mG<c-v>nGI# <c-v>表示ctrl+v

[文件目录管理]

1、删除几天以前的所有东西(包括目录名和目录中的文件)

1) find . -ctime +3 -exec rm -rf {} \;

2) find ./ -mtime +3 -print|xargs rm -f –r

2、在多级目录中查找某个文件的方法

1) find /dir -name filename.ext

2) du -a | grep filename.ext

3) locate filename.ext

3、删除软硬连接注意点

删除软件连接的时候一定要记得不要在删除的文件夹后加一斜杠,

rm -f filename/

会说这是一个文件夹不能删除

rm filename

会提示说是否要删除这个连接。

如果用的第一种可能会把其它文件都删除

4、删除目录中含输入关键字的文件

find /mnt/ebook/ -type f -exec grep "在此输入关键字" {} \; -print -exec rm {} \;

5、在当前目录下解压 rpm 文件

cat kernel-ntfs-2.4.20-8.i686.rpm | rpm2cpio | pax –r

6、用命令清空 Root 回收站中的文件

cd /var/.Trash-root

rm -rf *

7.删除文件大小为零的文件

rm -i `find ./ -size 0`

find ./ -size 0 -exec rm {} \;

find ./ -size |xargs rm -f &非常有效

for file in * #自己定义需要删除的文件类型

do

if [ ! -s ${file} ]

then

rm ${file}

echo "rm $file Success!"

fi

done

8.利用现存两个文件,生成一个新的文件

1) 取出两个文件的并集(重复的行只保留一份)

2) 取出两个文件的交集(只留下同时存在于两个文件中的文件)

3) 删除交集,留下其他的行

A cat file1 file2 | sort | uniq

B cat file1 file2 | sort | uniq -d

C cat file1 file2 | sort | uniq -u

9、使用shell命令修改多个文件

赵珂, 2007-08-20

注: 下面所有命令已在bash shell环境中测试

实例一: 修改当前目录所有的*.php5为*.php文件.

方法一

for old in *.php5; do cp $old `basename $old .php5`.php; done

使用循环语句发现当前目录的所有*.php5文件, 然后一个接一个的修改为*.php文件, 直到结束.

比如当前目录存在两个*.php5文件:

$ ll

total 8

-rw-rw-r– 1 zhaoke zhaoke 3 Aug 20 07:58 islab.php5

-rw-rw-r– 1 zhaoke zhaoke 3 Aug 20 08:10 zhaoke.php5

首先找到当前目录的islab.php5文件, 然后拷贝islab.php5, 'basename islab.php5 .php5′ .php

basename将返回"islab"字符, 然后增加.php到islab后面, 最后你得到islab.php文件.

shell命令运行后的当前目录:

$ for old in *.php5; do cp $old `basename $old .php5`.php; done

$ ll

total 16

-rw-rw-r– 1 zhaoke zhaoke 3 Aug 20 08:39 islab.php

-rw-rw-r– 1 zhaoke zhaoke 3 Aug 20 07:58 islab.php5

-rw-rw-r– 1 zhaoke zhaoke 3 Aug 20 08:39 zhaoke.php

-rw-rw-r– 1 zhaoke zhaoke 3 Aug 20 08:10 zhaoke.php5

你也可以修改shell命令中的cp为mv:

$ for old in *.php5; do mv $old `basename $old .php5`.php; done

$ ll

total 8

-rw-rw-r– 1 zhaoke zhaoke 3 Aug 20 07:58 islab.php

-rw-rw-r– 1 zhaoke zhaoke 3 Aug 20 08:10 zhaoke.php

方法二

$ rename .php5 .php *.php5

方法三

for x in *.php5; do n=${x/.php5/.php}; mv $x $n; done

方法四

for a in *php5 ; do mv $a ${a%%5} ; done

方法五

for a in *.php5; do t=`echo $a | sed 's/.php5$/.php/'`; mv $a $t; done

实例二: 把当前目录下所有文件及目录名中的大写字符改为小写符号

方法一:

1. 创建一个ucase脚本, 内容如下:

#!/bin/bash

# All names are converted to lower-case before matching

# [A-Z]* matches upper case names

for i in [A-Z]*

do

j=`echo $i | tr '[A-Z]' '[a-z]'`

mv $i $j

done

2. 赋予ucase脚本可执行权限

$ chmod +x ucase

3. 列出当前目录下的所有文件及目录

$ ll

total 16

-rw-rw-r– 1 zhaoke zhaoke 3 Aug 20 08:42 Islab.php

-rwxrwxr-x 1 zhaoke zhaoke 187 Aug 20 08:54 ucase

drwxrwxr-x 2 zhaoke zhaoke 4096 Aug 20 08:54 ZhaoKe

-rw-rw-r– 1 zhaoke zhaoke 3 Aug 20 07:58 zhaoke.php

4. 运行ucase脚本并查看结果

./ucase

mv: `ucase' and `ucase' are the same file

mv: `zhaoke.php' and `zhaoke.php' are the same file

$ ll

total 16

-rw-rw-r– 1 zhaoke zhaoke 3 Aug 20 08:42 islab.php

-rwxrwxr-x 1 zhaoke zhaoke 187 Aug 20 08:54 ucase

drwxrwxr-x 2 zhaoke zhaoke 4096 Aug 20 08:54 zhaoke

-rw-rw-r– 1 zhaoke zhaoke 3 Aug 20 07:58 zhaoke.php

方法二:

$ rename 'y/A-Z/a-z/' *

10、查找比某个时间早的文件

touch -t 12071200 oldfile

find /var/www/html -newer oldfile -print

find /var/www/html/ -path "/var/www/html/_node" -prune -newer oldfile -print

[系统与安全]

1、让用户的密码必须有一定的长度,并且符合复杂度

vi /etc/login.defs,修改 PASS_MIN_LEN

2、用 dat 查询昨天的日期

date --date='yesterday'

3、修改系统时

1) 设置你的时区: timeconfig 里选择Asia/Shanghai (如果你位于 GMT+8 中国区域)

2) 与标准时间服务器校准: ntpdate time.nist.gov

date -s "2003-04-14 cst",cst 指时区,时间设定用 date -s 18:10

修改后执行 clock -w 写到 CMOS

3) 将当前软件系统时间写入硬件时钟: hwclock –systohc

4、改变 redhat 的系统语言/字符集

修改 /etc/sysconfig/i18n 文件,如

LANG="en_US",xwindow会显示英文界面,

LANG="zh_CN.GB18030",xwindow会显示中文界面。

还有一种方法

cp /etc/sysconfig/i18n $HOME/.i18n

vi $HOME/.i18n 文件,如

LANG="en_US",xwindow会显示英文界面,

LANG="zh_CN.GB18030",xwindow会显示中文界面。

这样就可以改变个人的界面语言,而不影响别的用户

5、查看系统信息

cat /proc/cpuinfo - CPU (i.e. vendor, Mhz, flags like mmx)

cat /proc/interrupts - 中断

cat /proc/ioports - 设备 IO端口

cat /proc/meminfo - 内存信息(i.e. mem used, free, swap size)

cat /proc/partitions - 所有设备的所有分区

cat /proc/pci - PCI设备的信息

cat /proc/swaps - 所有 Swap 分区的信息

cat /proc/version - Linux 的版本号 相当于 uname -r

uname -a - 看系统内核等信息

6、让 linux自动同步时间

vi /etc/crontab

加上一句:

00 0 1 * * root rdate -s time.nist.gov

7、如何防止某个关键文件被修改

在 Linux 下,有些配置文件是不允许任何人(包括 root)修改的。为了防止被误删除或修改

可以设定该文件的"不可修改位(immutable) "。命令如下:

# chattr +i /etc/fstab

如果需要修改文件则采用下面的命令:

# chattr -i /etc/fstab

8、怎样让Linux成为"不死之身"

很多情况下在图形化界面会卡住,就像我们在Windows下会死机一样。但实际上没有完全死机,只是这个终端僵死了。

消除Xwindows下的死机现象。这样你的"不死之身"就打造完成

我们可以用两个常用的 方法来消除这种现象:第一,用键盘上的复合键"Ctrl+Alt+Backspace"来关闭当前正在运行的任务;第二,首先按住键盘上 的"Ctrl+Alt+F1"复合键,让系统切换到另一个操作台,然后登录到系统,再执行"#ps -ax/grep startx"命令,这将会列出你的Xserver的进程标识,接着在命令行中输入如下命令就能消除Xwindows下的死机现象:#kill -9 PID_Number,最后通过"Alt+F1"复合键返回到原来的平台。

8、查看系统日志信息,如:查看哪些用户什么时候登录过等。

/var/log/messages

/var/log/secure

lastlog

[管理与网络]

1、 lsof 用法小全

lsof abc.txt 显示开启文件 abc.txt 的进程

lsof -i :22 知道 22 端口现在运行什么程序

lsof -c nsd 显示 nsd 进程现在打开的文件

lsof -g gid 显示归属 gid 的进程情况

lsof +d /usr/local/ 显示目录下被进程开启的文件

lsof +D /usr/local/ 同上,但是会搜索目录下的目录,时间较长

lsof -d 4 显示使用 fd 为4 的进程

lsof -i [i] 用以显示符合条件的进程情况

语法: lsof -i[46] [protocol][@hostname|hostaddr][:service|port]

46 --> IPv4 or IPv6

protocol --> TCP or UDP

hostname --> Internet host name

hostaddr --> IPv4 位置

service --> /etc/service中的 service name (可以不止一个)

port --> 端口号(可以不止一个)

例子: TCP:25 - TCP and port 25

@1.2.3.4 - Internet IPv4 host address 1.2.3.4

tcp@ohaha.ks.edu.tw:ftp - TCP protocol host:ohaha.ks.edu.tw service name:ftp

lsof -n 不将 IP转换为 hostname,预设是不加上-n参数

例子: lsof -i tcp@ohaha.ks.edu.tw:ftp -n

lsof -p 12 看进程号为 12的进程打开了哪些文件

2、grep 不显示本身进程

#ps -aux|grep httpd|grep -v grep

grep -v grep可以取消显示你所执行的 grep 本身这个进程,-v 参数是不显示所列出的进程名

3、查看本机IP

ifconfig |grep "inet" |cut -c 0-36|sed -e 's/[a-zA-Z: ]//g'

hostname –i

4、查看有多少活动的Httpd进程

#!/bin/sh

while (true)

do

pstree |grep "*\[httpd\]$"|sed 's/.*-\([0-9][0-9]*\)\*\[httpd\]$/\1/'

sleep 3

done

同样可以引用到其它的进程

5、设置 com1口,让超级终端通过 com1口进行登录

第一步:确认有/sbin/agetty,编辑/etc/inittab,添加

7:2345:respawn:/sbin/agetty /dev/ttyS0 9600

9600bps 是因为连路由器时缺省一般都是这种速率,也可以设成

19200、38400、57600、115200

第二步:修改/etc/securetty,添加一行:ttyS0,确保 root 用户能登录

第三步:重启机器,就可以拔掉鼠标键盘显示器(启动时最好还是要看看输出信息)了

6、查找或删除正在使用某文件的进程

fuser filename

fuser -k filename

7、已知网络中一个机器的硬件地址,如何知道它所对应的 IP地址

在 Linux 下,假定要查"00:0A:EB:27:17:B9"这样一个硬件地址所对应的 IP 地址,可以使

用以下命令:

# cat /proc/net/arp |grep 00:0A:EB:27:17:B9

192.168.2.54 0x1 0x6 00:0A:EB:27:17:B9 *eth2

另外,还可以用"arp -a"命令查询:

# arp –a|grep 00:0A:EB:27:17:B9

(192.168.2.54)at 00:0A:EB:27:17:B9[ether] on eth2

8、在 Linux下如何绑定 IP地址和硬件地址

可以编辑一个地址对应文件,里面记录了 IP地址和硬件地址的对应关系,然后执行"arp –

f 地址对应文件"。如果没有指定地址对应文件,则通常情况下一默认文件/etc/ethers为准。

地址对应文件的格式如下:

192.168.0.1 00:0D:61:27:58:93

192.168.0.2 00:40:F4:2A:2E:5C

192.168.0.3 00:0A:EB:5E:BA:8E

9、更改 eth0是否混杂模式(混杂模式可以监听其它主机的信息)

网卡 eth0 改成混杂模式:

ifconfig eth0 promisc

关闭混杂模式:

ifconfig eth0 –promisc

10、linux下清空 arp表的命令

#arp -d -a(适用于 bsd)

for HOST in `arp | sed '/Address/d' | awk '{ print $1}'` ; do arp -d $HOST; done

11、如何得到网卡的 MAC地址

arp -a | awk '{print $4}'

ifconfig eth0 | head -1 | awk '{print $5}'

12、一个网卡绑定多 ip

方法一、建立eth0:1在网卡后加冒号和数字的文件

cp /etc/sysconfig/network-scripts/eth0 /etc/sysconfig/network-scripts/eth0:1

再修改下eth0:1就可以了.

方法二、

在/etc/sysconfig/network-scripts/下创建一个文件:ifcfg-ethX-rangeX ("X"为网卡号)

文件内容:

IPADDR_START=<start ip>

IPADDR_END=<end ip>

CLONENUM=0

可以有 256个 ip

13、一个 ip如何绑定两块网卡

假设 192.168.0.88 是ip,192.168.0.1 是网关:

/sbin/modprobe bonding miimon=100 mode=1

/sbin/ifdown eth0

/sbin/ifdown eth1

/sbin/ifconfig bond0 192.168.0.88

/sbin/ifenslave bond0 eth0 eth1

/sbin/route add default gw 192.168.0.1

14、设置ssh 上来能不自动断线

修改自己 HOME 目录下的.bash_profile文件,加上

export TMOUT=1000000 (以秒为单位)

然后运行 source .bash_profile

15、mount 局域网上其他windows机器共享出的目录

mount -t smbfs -o username=guest,password=guest //machine/path /mnt/cdrom

16、向登陆到同一台服务器上的所有用户发一条信息

1)输入 wall并回车

2)输入要发送的消息

3)结束时按"Control-d"键,消息即在用户的控制窗口中显示

17、向远程机器上的所有用户发送消息

使用 rwall(向所有人远程写)命令同时发送消息到网络中的所有用户。

rwall hostname file

当使用 CDE或 OpenWindows 等窗口系统时,每个窗口被看成是一次单个的登录;

如果用户登录次数超过一次则消息直接发送到控制窗口

18、向网络中的所有用户发送消息

发送消息到网络中的所有用户

1)输入 rwall -n netgroup 并回车

2)输入要发送的消息

3)结束时按"Control-d"键,消息即在系统每个用户的控制窗口中显示,下面是系统管理员

发消息到网络组 Eng 每个用户的例子:

% rwall -n EngSystem will be rebooted at 11:00.(Control-d)

%

用户控制窗口中的消息:Broadcast message from root on console…System will be rebooted at

11:00.EOF

注意:也可以通过 rwall hostname(主机名)命令到系统的所有用户

19、 将 top的结果输出到文件中

top -d 2 -n 3 -b >test.txt

可以把 top 的结果每隔 2秒,打印 3次,这样后面页的进程也能够看见了

20、装双系统不能看到另一个系统的解决办法

首先光盘启动,进入 rescue 模式,运行 GRUB,进入 grub 提示符 grub>,然后敲入下面的

语句,重启就好了。

root (hd0,2),setup (hd0)

21、压缩传输文件或目录

传输到远程:tar czf - www | ssh server "tar zxf -"

压缩到远程:tar czf - www | ssh server "cat > www.tar.gz"

解压到远程:ssh server "tar zxf -" < www.tar.gz

解压到本地:ssh server "cat www.tar.gz" | tar zxf -

22、命令行下发送带附件的邮件

方法 1. uuencode <in_file> <remote_file> | mail -s "title" mail@address

<in_file> 本地需要作为附件的文件名。

<remote_file> 邮件中的附件文件名,可以和<in_file>不同,其实内容一样。

方法 2. cat <mailcontent.txt> | mutt -s "title" -a <attachfile> mail@address

<mailcontent.txt>邮件正文内容。

<attachfile>本地需要作为附件的文件名。

23、一条命令杀死多个进程

有时停一个服务,进程老停不下来,就要Kill掉。但很多程序都是同时开很多的进程。ps -aux | grep name后一个个删除,这样太麻烦了。可以用killall命令,像apache的进程可以用killall httpd就可以把所以有的进程一条命令就删除掉了。如果有僵死进程就可以用第6条来处理。

24、Kill命令小技巧

kill -HUP PID 重新加载进程

kill -TERM PID 结束进程

kill -KILL PID 杀死进程

-HUP可用数字-1代替

-TERM可用数字-15代替

-KILL可用数字-9代替

25、cd命令的几个小技巧

说cd这个命令是Linux上使用率最高的两个命令之一不为过吧(另一个当然是ls了)

cd - #回到上次所在目录,这个技巧我原来还真是不知道,感觉还是比较有用,省略了很多输入。

cd !$ #把上个命令的参数作为输入。(这个在其它命令也是通用的,一定要习惯运用会简化很多工作)

cd #回到主目录

cd ~ #同样也是回到主目录

cd .. #回到上一级目录

cd ../../ #回到上上级目录

下面连贯的做一个例子来说明:

引用

ocean@flower-laptop:~$ pwd #查看当前目录路径

/home/ocean

ocean@flower-laptop:~$ sudo tar xf wordpress.tar.gz -C /opt/lampp/htdocs/wordpress #解压压缩包到/opt/lampp/htdocs/wordpress目录

ocean@flower-laptop:~$ cd !$ #执行cd !$把上个命令最后的参数作为输入,即/opt/lampp/htdocs/wordpress

cd /opt/lampp/htdocs/wordpress

ocean@flower-laptop:/opt/lampp/htdocs/wordpress$ pwd #查看当前目录路径

/opt/lampp/htdocs/wordpress

ocean@flower-laptop:/opt/lampp/htdocs/wordpress$ cd #执行cd命令回到了主目录

ocean@flower-laptop:~$ pwd #查看当前目录路径

/home/ocean

ocean@flower-laptop:~$ cd - #执行cd -,回到上次所在目录。

/opt/lampp/htdocs/wordpress

ocean@flower-laptop:/opt/lampp/htdocs/wordpress$ pwd #查看当前目录路径

/opt/lampp/htdocs/wordpress

26. 如果SWAP(交换空间)不够了,要增加怎么办?只要你的硬盘上有空闲的空间,直接用命令:mkswape/dev/hda(假设你的驱动器是/dev /hda),swapon/dev/hda;要自动启动SWAPE,可以把新的分区加到/etc/fstab中去,照着原来SWAP的写就行了。 用"free" 检查 你SWAP的大小,Linux支持最多16个交换分区,每个交换分区最大128MB,没有空闲分区的时候,可以用个大文件来建立,用命令"man mkswap"查看帮助。

# dd if=/dev/zero of=swapfile bs=1024 count=8192

# mkswap swapfile 8192

# sync

# swapon swapfile

27、一次解压多个.tar.gz文件

find ./ -name '*.tar.gz' -exec tar zxvf {} \; -print

28、看到第二点查询昨天的日期,朋友突然发现了其它的单词都可以查询想要的日期,只要你知道有关时间的英文单词。现在把结果贴出来,做什么用的一看就知道。

[root@web ~]# date 注意:这是当前时间

Mon Sep 3 19:30:22 CST 2007

[root@web ~]# date --date='yesterday'

Sun Sep 2 19:32:05 CST 2007

[root@web ~]# date --date='today'

Mon Sep 3 19:32:13 CST 2007

[root@web ~]# date --date='year'

Wed Sep 3 19:32:35 CST 2008

[root@web ~]# date --date='tomorrow'

Tue Sep 4 19:33:28 CST 2007

[root@web ~]# date --date='month'

Wed Oct 3 19:33:49 CST 2007

[root@web ~]# date --date='hour'

Mon Sep 3 20:34:33 CST 2007

28、查看Linux系统下网卡物理连接是否正常。

在Linux下很有趣,不管你插了网线还是没有都可以Ping到你配置的IP,这就造成一个假象以为物理连接是正常的。怎么来确定你的网卡与网线是否连接正常呢?

ethtool eth0

最后有一个Link detected: yes (Yes表示连接正常,No表示连接不正常)

[Mysql维护]

1、mysql 的数据库存放在什么地方

1) 如果使用 rpm包安装,应该在/var/lib/mysql 目录下,以数据库名为目录名

2) 如果源码安装在/usr/local/mysql中,应该在/usr/local/mysql/var中,以数据库名为目录名

2、 从 mysql 中导出和导入数据

导出数据库

mysqldump 数据库名 > 文件名

导入数据库

mysqladmin create 数据库名

mysql 数据库名 < 文件名

3、忘了 mysql 的 root 口令怎么办

# service mysql stop

# mysqld_safe --skip-grant-tables &

# mysqladmin -u user password 'newpassword''

# mysqladmin flush-privileges

4、 mysqld 起来了,却无法登录,提示"/var/lib/mysql/mysql.sock"不存在

这种情况大多数是因为你的 mysql 是使用 rpm 方式安装的,它会自动寻找

/var/lib/mysql/mysql.sock 这个文件,

通过 unix socket 登录 mysql。

常见解决办法如下:

1)创建/修改文件 /etc/my.cnf,至少增加/修改一行

[mysql]

[client]

socket = /tmp/mysql.sock

#在这里写上你的 mysql.sock 的正确位置,通常不是在 /tmp/ 下就是在 /var/lib/mysql/ 下

2)指定 IP地址,使用 tcp 方式连接mysql,而不使用本地 sock 方式

#mysql -h127.0.0.1 -uuser -ppassword

3)为 mysql.sock 加个连接,比如说实际的 mysql.sock 在 /tmp/ 下,则

# ln -s /tmp/mysql.sock /var/lib/mysql/mysql.sock即可

5、 导出数据的几种常用方法

1)使用 mysqldump

#mysqldump -uuser -ppassword -B database --tables table1 --tables table2 >

dump_data_20051206.sql

详细的参数

2)backup to语法

mysql>BACKUP TABLE tbl_name[,tbl_name...] TO '/path/to/backup/directory';

详细请查看 mysql 手册

3)mysqlhotcopy

#mysqlhotcopy db_name [/path/to/new_directory]



#mysqlhotcopy db_name_1 ... db_name_n /path/to/new_directory



#mysqlhotcopy db_name./regex/

详细请查看 mysql 手册

4)select into outfile

详细请查看 mysql 手册

5)客户端命令行

#mysql -uuser -ppassword -e "sql statements" database > result.txt

以上各种方法中,以 mysqldump 最常用

6、 如何在命令行上执行 sql 语句

#mysql -uuser -ppassword -e "sql statements" database

7、 导入备份出来文件的常见方法

1)由 mysqldump 出来的文件

#mysql -uuser -ppassword [database] < dump.sql

2)文件类型同上,使用 source 语法

mysql>source /path_to_file/dump.sql;

3)按照一定格式存储的文本文件或 csv 等文件

#mysqlimport [options] database file1 [file2....]

详细请查看 mysql 手册

4)文件类型同上,也可以使用 load data 语法导入

详细请查看 mysql 手册

NTP时间服务方案[原创]

作者:Ajian 发布时间:January 16, 2009 分类:网络服务,学习笔记

[前言]

随着服务器的增加和应用对时间的依赖性,在一个大的网站中时间服务器应该是必不可少的,我们应该尽力的使所有的服务器都是同一种配置,这样即有利我们配置更有利于我们维护。

[问题]

如果时间差别太大,会产生很多的问题:1、系统时间旧于软件创建的时间,造成软件无法安装2、系统时间不稳定,造成数据同步将出现问题3、多台计划任务不能统一准时执行4、对时间依赖较大的软件会出现混乱,如论坛贴子的发布等

[方案]

时间的同步这里采用NTP,NTP类似于DNS可以实现分布式的同步,避免网络延时造成的影响。服务器可以单独直接和上层公共时间服务器同步,这样的缺点时网络的延时可能造成各主机的时间并不一定统一和准确。最好是在内部自己建立一个对外同步的时间服务器,其它主机都跟内部这台时间服务器进行同步。

[部署]

环境:

1、系统:CentOS 4 CentOS 5.2 slackware 12 slackware 11 slackware 10(我们的主机较多、 版本较多)2、时间服务IP192.168.0.3 192.168.0.4

安装:

不管是服务器端还是客户端都需要安装ntp的软件。建议:像这种辅助性的服务安装建议用系统自带的,没有必要弄得很复杂。CentOSyum -y install ntp
Slackware: slackpkg install ntp
(这个是安装有slackpkg这个包管理工具的)当然也可以下相应的rpmtgz

主要配置:

ntp只有一个配置文件就是/etc/ntp.conf还有些相关的有用的配置文件和命令在后面会有提及。

服务器端ntp.conf

# /etc/ntp.conf: Configuration file for ntpd.

#

server 127.127.1.0 # local clock

fudge 127.127.1.0 stratum 10

1、以上为原本内定的一个内部时间资料,不需要更动他



server 1.asia.pool.ntp.org prefer

server 0.asia.pool.ntp.org

server 2.asia.pool.ntp.org

server 3.asia.pool.ntp.org

2、上面四条为设置上层来源的四个地址,注意这个地址是各个国家和地区有不同 而且还有优劣性,

这四个地址都是亚洲地区的,可以自己在服务器上PING四个地址判断其优劣性,我的服务器1.asia.pool.ntp.org速度快,并且给了prefer的优先级。

# Drift file. Put this in a directory which the daemon can write to.

# No symbolic links allowed, either, since the daemon updates the file

# by creating a temporary in the same directory and then rename()'ing

# it to the file.

3、调整时间差异的功能,保持默认值就可以了

driftfile /etc/ntp/drift

#multicastclient # listen on default 224.0.1.1

broadcastdelay 0.008



# Access Controls

# Keys file. If you want to diddle your server at run time, make a

# keys file (mode 600 for sure) and define the key number to be

# used for making requests.

# PLEASE DO NOT USE THE DEFAULT VALUES HERE. Pick your own, or remote

# systems might be able to reset your clock at will.

#keys /etc/ntp/keys

#trustedkey 65535

#requestkey 65535

#controlkey 65535



# Don't serve time or stats to anyone else by default (more secure)

restrict default ignore

4、以下都是访问控制

# Trust ourselves. :-)允许自己

restrict 127.0.0.1

# restrictions for ntp pools限制的NTP

restrict 0.asia.pool.ntp.org mask 255.255.255.255 nomodify notrap noquery

restrict 1.asia.pool.ntp.org mask 255.255.255.255 nomodify notrap noquery

restrict 2.asia.pool.ntp.org mask 255.255.255.255 nomodify notrap noquery

restrict 3.asia.pool.ntp.org mask 255.255.255.255 nomodify notrap noquery



# permit all the internal private network servers to query the time允许访问的网段,对客户端的

restrict 192.168.0.0 mask 255.255.255.0 nomodify notrap

restrict其中parameter的参数:

  • ignore拒绝所有类型的NTP连线;
  • nomodiy用户端不能更改NTP伺服器的时间参数,这即表示用户端不能使用ntpcntpq这两支程式来修改伺服器。 但用户端仍可透过这部主机来进行网路校时的;

  • noquery用户端不能够使用ntpq, ntpc等指令来查询时间伺服器,等於不提供NTP的网路校时罗;

  • notrap不提供trap这个远端事件登录(remote event logging)的功能。

  • notrust拒绝没有认证的用户端。

那如果没有任何参数的话,这表示『该IP或网段不受任何限制』的意思!

客户端ntp.conf

# /etc/ntp.conf

#

server 192.168.0.3

server 192.168.0.4

driftfile /etc/ntp/drift

restrict default ignore

restrict 127.0.0.1

restrict 192.168.0.3 mask 255.255.255.255 nomodify notrap noquery

restrict 192.168.0.4 mask 255.255.255.255 nomodify notrap noquery

客户端的ntp.conf跟服务器端一样的语法 ,只是将内部设置的时间服务器做为上层伺服务器源主机。

次要配置:

1、修改/etc/sysconfig/ntpd

# Drop root to id 'ntp:ntp' by default.

OPTIONS="-u ntp:ntp -p /var/run/ntpd.pid"



# Set to 'yes' to sync hw clock after successful ntpdate

SYNC_HWCLOCK=yes

将上面的no改为yes这个是系统时间跟BIOD时间同步的一个设置

注意:这个文件在slackware是没有的,我也单独添加了这个文件不知道是否是正常生效了。

# Additional options for ntpdate

NTPDATE_OPTIONS=""

2、添加启动项

如果是用系统的包安装的:CentOS: 1)setup选择system service 2) chkconfig ntpd on
Slackware:
第一步chmod +x /etc/rc.d/rc.ntpd第二步添加到启动中/etc/rc.d/rc.M

# Start the Network Time Protocol daemon:

if [ -x /etc/rc.d/rc.ntpd ]; then

sh /etc/rc.d/rc.ntpd start

fi

3、查看和修改时区

查看时区cat /etc/sysconfig/clockslackware没有)显示的是地区date -R显示的是时区号

修改时区# tzselect
# timeconfig (
仅限于RedHat LinuxCentOS)

3.复制相应的时区文件,替换系统时区文件;或者创建链接文件cp /usr/share/zoneinfo/$主时区/$次时区/etc/localtime

在中国可以使用:

cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime

启动服务

CentOS: 1)service ntpd restart 2) /etc/init.d/ntpd restart
Slackware:1)/etc/rc.d/rc.ntpd restart

查看结果

注意:一般服务启动15分钟内才会同步时间,这个时间不是很固定所以要注意,不过还是有判断的标准的。

1、(只适用于centos redhat这种)ntpstat

synchronised to NTP server (192.168.0.4) at stratum 4 <==同步的服务器

time correct to within 174 ms <==服务器与客户端的时间差

polling server every 1024 s <==下次同步的时间

这个可以很清楚的看到同步的情况,可惜slackware下没有看到这个命令

2ntpq -p

remote refid st t when poll reach delay offset jitter

=============================================================

+192.168.0.3 61.129.66.79 3 u 328 1024 377 1.142 -62.973 0.257

*192.168.0.4 61.129.66.79 3 u 763 1024 377 1.188 22.298 3.615

这个ntpq -p可以列出目前我们的NTP与相关的上层NTP的状态,上头的几个栏位的意义为:

  • remote:亦即是NTP主机的IP或主机名称~注意最左边的符号, 如果有『+』代表目前正在作用当中的上层NTP,如果是『*』代表也有连上线,不过是作为次要连线的NTP主机。

  • refid:参考的上一层NTP主机的位址

  • st:就是stratum阶层!

  • when:几秒钟前曾经做过时间同步化更新的动作;

  • poll:下一次更新在几秒钟之后;

  • reach:已经向上层NTP伺服器要求更新的次数

  • delay:网路传输过程当中延迟的时间,单位为10^(-6)

  • offset:时间补偿的结果,单位与10^(-6)

  • jitterLinux系统时间与BIOS硬体时间的差异时间, 单位为10^(-6)秒。

3ntptrace -n 127.0.0.1

ntptrace -n 127.0.0.1



127.0.0.1: stratum 4, offset -0.019501, synch distance 0.298589

192.168.0.4: stratum 3, offset 0.005055, synch distance 0.200525

61.129.66.79: stratum 2, offset 0.006232, synch distance 0.123439

209.81.9.7: stratum 1, offset -0.000008, synch distance 0.000465, refid 'GPS'

其它:

时间设置:

如果时间差别太大、或者在没有时间同步服务器的情况下可以用手动设置的方法

时间

1、查看时间和日期

date

2、设置时间和日期

date -s "dd/mm/yyyy hh:mm:ss"

将系统日期设定成1996610日的命令

date -s 1996-06-10

将系统时间设定成下午1520秒的命令

date -s 13:52:00

3.将当前时间和日期写入BIOS,避免重启后失效

hwclock -w

简单的客户端同步法:

如果主机不算太多的话 加一条到计划任务就可以了。

#crontab -e
10 5 * * * root /usr/sbin/ntpdate 1.asia.pool.ntp.org && /sbin/hwclock -w

参考文章 :

鳥哥的Linux私房菜http://linux.vbird.org/linux_server/0440ntp.php

wp-utf8-excerpt 首页摘要插件

作者:Ajian 发布时间:January 15, 2009 分类:杂记摘要

Author: Betty

Main features of the plugin:

  1. It supports multibyte language (such as Chinese). It will not produce gibberish as some other excerpt plugins do.
  2. The html tags in the original posts, i.e., the font styles, colors, hyperlinks, pictures and such are preserved in the excerpt.
  3. For better readability, it displays 300 characters for each post on the homepage and 150 characters for each post on archive pages.

Installation

  1. Unzip and upload the wp-utf8-excerpt directory to the /wp-content/plugins/ directory
  2. Activate the plugin through the 'Plugins' menu in WordPress
  3. In your theme directory, edit the index.php file by changing
    <?php the_content(); ?>

to

<?php
if (is_single() or is_page()) {
the_content();
} else {
the_excerpt();
}
?>

http://wordpress.org/extend/plugins/wp-utf8-excerpt/

解决vim不显示彩色

作者:Ajian 发布时间:January 14, 2009 分类:杂记摘要

自己笔记本上用的ubuntu下的vim一直不显示彩色,有点不太爽。现在解决了。
1、首先肯定是要安装vim 有人说需要安装vim-x11 ubuntu上倒是不用
2、关键:
1)cp /etc/vim/vimrc ~/.vimrc
2) vim ~/.vimrc
去掉"syntax on 前的"就可以了 更多的功能可以看这个配置文件。

VI高级命令集锦及VIM应用实例

作者:Ajian 发布时间:January 14, 2009 分类:学习笔记,杂记摘要

1.交换两个字符位置

xp

2.上下两行调换

ddp

3.把文件内容反转

:g/^/m0

4.上下两行合并

J

5.删除所有行

dG

6.从当前位置删除到行尾

d$

7.从当前位置复制到行尾

y$ 如果要粘贴到其他地方 p 就可以了

由于vi 是建立在 EX 上的 所以 当键入 : 时就来到了 EX 命令状态

8.

:ab string strings

例如 ":ab usa United States of America" ,

当你在文见里插入 usa 时

United States of America 就蹦出来了

9.

:map keys new_seq

定义你当前 键盘命令

10.

:set [all]

vi or ex 的编辑状态

如 显示每行 :set nu

11.

在命令状态下,nyy表示拷贝从光标行起的下n行内容,p表示paste,可刚复制的内容粘贴在光标处的下面。

12.

单个字符替换用r,覆盖多个字符用R,用多个字符替换一个字符用s,整行替换用S

13.

:%s/old_word/new_word/g

这个指令是于在整个文件中替换特定字符串

14.光标控制

k:上移 nk 上移n行

j:下移 nj 下移n行

将光标移到第n行,按下 mk

将光标移到第m行,按下 "ay'k

即将第n到m的行存到a寄存器,以此类推,b,c........寄存器等

这样就可以将你常用的需要复用的内容粘贴到不同的寄存器中以备用

想粘贴到某处,直接将光标移到某地,按下 'ap 即可,以此类推,b,c........寄存器等

在当前屏幕中

H 跳到第一行

M 跳到中间一行

L 跳到最后一行

15.

表8-2 删除命令

删除命令操作

d l 删除当前字符(与x命令功能相同)

d 0 删除到某一行的开始位置

d ^ 删除到某一行的第一个字符位置(不包括空格或TA B字符)

d w 删除到某个单词的结尾位置

d 3 w 删除到第三个单词的结尾位置

d b 删除到某个单词的开始位置

d W 删除到某个以空格作为分隔符的单词的结尾位置

d B 删除到某个以空格作为分隔符的单词的开始位置

d 7 B 删除到前面7个以空格作为分隔符的单词的开始位置

d) 删除到某个语句的结尾位置

d 4) 删除到第四个语句的结尾位置

d( 删除到某个语句的开始位置

d } 删除到某个段落的结尾位置

d { 删除到某个段落的开始位置

d 7 { 删除到当前段落起始位置之前的第7个段落位置

d d 删除当前行

d /t e x t 删除从文本中出现" t e x t"中所指定字样的位置,一直向前直到下一个该字样所出现的

位置(但不包括该字样)之间的内容

d fc 删除从文本中出现字符"c"的位置,一直向前直到下一个该字符所出现的位置(包括

该字符)之间的内容

d tc 删除当前行直到下一个字符" c"所出现位置之间的内容

D 删除到某一行的结尾

d $ 删除到某一行的结尾

5 d d 删除从当前行所开始的5行内容

d L 删除直到屏幕上最后一行的内容

d H 删除直到屏幕上第一行的内容

d G 删除直到工作缓存区结尾的内容

d 1 G 删除直到工作缓存区开始的内容

修改命令操作

c l 更改当前字符

c w 修改到某个单词的结尾位置

c 3 w 修改到第三个单词的结尾位置

c b 修改到某个单词的开始位置

c W 修改到某个以空格作为分隔符的单词的结尾位置

c B 修改到某个以空格作为分隔符的单词的开始位置

c 7 B 修改到前面7个以空格作为分隔符的单词的开始位置

c 0 修改到某行的结尾位置

c) 修改到某个语句的结尾位置

c 4) 修改到第四个语句的结尾位置

c( 修改到某个语句的开始位置

c } 修改到某个段落的结尾位置

c { 修改到某个段落的开始位置

c 7 { 修改到当前段落起始位置之前的第7个段落位置

c tc 修改当前行直到下一个字符c所出现位置之间的内容

C 修改到某一行的结尾

c c 修改当前行

5 c c 修改从当前行所开始的5行内容

.重复上一次修改!

表8-4 替换命令

替换命令操作

s 将当前字符替换为一个或多个字符

S 将当前行替换为一个或多个字符

5 s 将从当前字符开始的5个字符替换为一个或多个字符

vi替换使用规则:

:g/s1/s/s2/s3/g

第一个g表示对每一个包括s1的行都进行替换,第二个g表示对每一行包括s1的行所有的s2都用s3替换

s表示替换,s2是要被替换的字符串,他可以和s1相同(如果相同的话用//代替),s3是替换字符串

16.

fx

往右移动到 x 字符上

Fx

往左移动到 x 字符上

tx

往右移动到 x 字符前

Tx

往左移动到 x 字符后

(注意:以上四个命令中,其中x是键入的字符)

;

分号,配合 f 和 t 使用,重复一次

,

逗号,配合 f 和 t 使用,反方向重复一次

17. vi 环境选项 Solaris ksh

noautoindent nomodelines noshowmode

autoprint nonumber noslowopen

noautowrite nonovice tabstop=8

nobeautify nooptimize taglength=0

directory=/var/tmp paragraphs=IPLPPPQPP LIpplpipnpbtags=tags /usr/lib/tags

noedcompatible prompt tagstack

noerrorbells noreadonly term=vt100

noexrc redraw noterse

flash remap timeout

hardtabs=8 report=5 ttytype=vt100

noignorecase scroll=11 warn

nolisp sections=NHSHH HUuhsh+c window=23

nolist shell=/bin/ksh wrapscan

magic shiftwidth=8 wrapmargin=0

mesg noshowmatch nowriteany

For C-Shell:

setenv EXINIT "set nu"

For Bourne or Korn Shell:

EXINIT="set nu"; export EXINIT

For Korn Shell Only (alternate method):

typeset -x EXINIT="set nu"

在 .profile 里设置 vi 的环境选项 , 以上均测试过

18.标记文本

mchar

用字母char标记当前光标的位置

`char

移至char所标记处

'char

移至char标记所在行的开头处

"

移至当前行上一次所在位置(在光标移动之后)――一个双引号

''

移至当前行上第一次所在位置的行的开头处(在光标移动之后)――两个单引号

19.

同时vi多个文件时,CTRL-SHIFT-6回到上一个文件,在本次vi的文件和上次vi的文件之间切换。

但是我发现一个BUG:在用CTRL-SHIFT-6切换到上一个文件后,用:args查看多文件vi状态时,

屏幕底部仍然显示目前vi的是刚才的文件。

(在HP-UX,Solaris,AIX上通过)

也可以使用:

:e#

进行切换

20.

sco 下VI 要在文本前同样的字符加用

%s/^/要加的内容/g 要在文本后同样的字符加

%s/$/要加的内容/g

21.

如何去掉文本中的 ^M 硬回车?不必用binary传回去再ascii传回来的方式,用shell或者unix语句实现。

cat filename |tr -d '\015' >newfile

不同的unix系统还存在一些其他不同的命令,如:doscp

sed 也可以实现这个功能.

dos2unix filename filename2

反之

unix2dos filename filename2

在vi 中用:$s/^M//g

^是crtl-V crtl-M

22.如何在"unix命令行"下将一个文件的某字符串用另一个串换掉

sed 's/string1/string2/gp' file1 > file2

23.将/etc/hosts下所有的地址都ping 2次

1 #/usr/bin/sh

2 #grad /etc/hosts and ping each address

3 cat /etc/hosts|grep -v '^#' | while read LINE

4 do

5 ADDR=`awk '{print $1}'`

6 for MACHINE in $ADDR

7 do

8 ping $MACHINE -n 2

9 done

10 done

24

到前一个函数[[ ,到下一个函数]] ,括号配对% ,交叉参考Ctrl_] (事先用ctags做索引),回来用e# ` 编辑一个函数:vi -t 函数名 ,编辑加密文本vi -X

25

在插入模式下ctrl+p,自动补齐剩余单词,以赖规则:tags,以有的单词等等

当今世界,文本编辑器种类繁多,大有"乱花渐欲迷人眼"之势。中国有句古语:手巧不如家什妙,作为IT业的专业人士,选择一款优秀的编辑软件至关重要。笔者认为:LINUX下的VIM※以其强大的功能和无穷的魅力将使您终生受益。

作者:闫石 (iloveibm@163.com)

来自:http://www-900.ibm.com/developerWorks/cn/linux/l-tip-prompt/tip15/index.shtml

由于被广泛移植,无论是PC机的DOS和WINDOWS,还是RISC/6000的AIX,乃至于IBM的大型机S/390,都能见到VIM的身影。然 而,对于初学者,VIM的用户界面与使用方法非常不符合常规,甚至认为它比较混乱,无所适从。事实上,VIM编辑器是专门为经验丰富的用户设计的,它的界 面和使用方法提供了更快的速度和更强的功能。对于熟知它的用户,VIM的许多特性节省了时间和击键次数,并可以完成一些其他编辑器无法完成的功能。

学习的最好方法是实践,唯有如此,才能真正掌握其中的精髓。文中列举的实例,都是笔者在实际工作中遇到的,具有一定的代表性,请大家在阅读的过程中仔细体会。

好了,现在让我们共同畅游神奇的VIM的世界!

例一、两个常用的指令序列

xp 左右交换光标处两字符的位置。

ddp 上下交换光标处两行的位置。

例二、重复输入同一字符

有时,我们可能想多次输入同一字符,VIM的插入功能可以很好的完成这项工作

命令 80i=^ESC 一次可以输入80个字符= ,当然,80a=^ESC 也可以完成上述功能。

请注意:此处的^ESC表示键盘左上方上的ESC键。

例三、将两个文本数据文件按行逐条合并,并给出标尺

数据文件1内容如下:

1-----

2-----

3-----

数据文件2内容如下:

1=====

2=====

3=====

要求的结果如下:

|--------1---------2---------3---------4---------5

1-----

1=====

|--------1---------2---------3---------4---------5

2-----

2=====

|--------1---------2---------3---------4---------5

3-----

3=====

也许您会说,这还不简单,无非是反复拷贝、粘贴,任何一款文本编辑器都能完成上述功能。可是,如果这两个文件都很大,每个文件都成千上万行,恐怕简单的 拷贝、粘贴就难以胜任了。因此,我们所关心的,是找到一种行之有效的方法,把枯燥乏味的工作留给计算机,我们只需发布指令。为达到此目的,请按以下步骤执 行:

㈠、将两文件合并,结果如下

1-----

2-----

3-----

1=====

2=====

3=====

㈡、在两文件头尾相接的地方插入标志行,用以区分两个文件,本文采用的是一整行!字符

1-----

2-----

3-----

!!!!!!!!!!!!!!!!!!!!!!!!

1=====

2=====

3=====

㈢、在标志行的下方输入标尺

1-----

2-----

3-----

!!!!!!!!!!!!!!!!!!!!!!!!

|--------1---------2---------3---------4---------5

1=====

2=====

3=====

㈣、执行宏命令脚本merge_2r.vim,即在VIM编辑器中按如下键 :so merge_2r.vim 回车

㈤、按下键盘上的=键,执行的结果如下

|--------1---------2---------3---------4---------5

1-----

1=====

|--------1---------2---------3---------4---------5

2-----

2=====

|--------1---------2---------3---------4---------5

3-----

3=====

|--------1---------2---------3---------4---------5

!!!!!!!!!!!!!!!!!!!!!!!!

|--------1---------2---------3---------4---------5

㈥、将最后三行删除,即可得到我们需要的结果

|--------1---------2---------3---------4---------5

1-----

1=====

|--------1---------2---------3---------4---------5

2-----

2=====

|--------1---------2---------3---------4---------5

3-----

3=====

怎么样,简单吗?请大家自己实际尝试一下。下面,我来详细讲解宏命令脚本merge_2r.vim 。

该脚本内容如下:

"--------------------------------------------------------------------

"Macro Function : Merge File1 And File2,Have Ruler in every record

" Date : 2001/12/01

" Author : Yan Shi

"--------------------------------------------------------------------

"1-----

"2----- } Sample File1

"3-----

"!!!!!!!!!!!!!!!!!!!!!!!! Flag Row

"|--------1---------2---------3---------4---------5 Ruler

"1=====

"2===== } Sample File2

"3=====

"--------------------------------------------------------------------

:1

:map = ma/!!!!!^M+:.co 'a-1^M/!!!!!^M2+:.m'a^M+=

前14行每行都以"开始,表明该行是注释行,实际并不执行,只是方便读者阅读,只有最后两行才是真正的代码行。请注意:本例中的^M表示键盘上的回车键,并非^和M两个字符。为了讲述清楚,我把命令行分解开,逐一说明。

首先将第一行置为当前行,然后执行map命令,将一大串VIM指令映像给字符=。这一大串VIM指令共分9步执行:

ma 将数据文件一的第一行标记为a

1-----

2-----

3-----

!!!!!!!!!!!!!!!!!!!!!!!!

|--------1---------2---------3---------4---------5

1=====

2=====

3=====

/!!!!!^M 找到标志行,置为当前行

1-----

2-----

3-----

!!!!!!!!!!!!!!!!!!!!!!!!

|--------1---------2---------3---------4---------5

1=====

2=====

3=====

+ 光标下移一行,即把标尺行置为当前行

1-----

2-----

3-----

!!!!!!!!!!!!!!!!!!!!!!!!

|--------1---------2---------3---------4---------5

1=====

2=====

3=====

:.co 'a-1^M 把标尺行复制到标记行(数据文件一的第一行)的上方

|--------1---------2---------3---------4---------5

1-----

2-----

3-----

!!!!!!!!!!!!!!!!!!!!!!!!

|--------1---------2---------3---------4---------5

1=====

2=====

3=====

/!!!!!^M 再次找到标志行,置为当前行

|--------1---------2---------3---------4---------5

1-----

2-----

3-----

!!!!!!!!!!!!!!!!!!!!!!!!

|--------1---------2---------3---------4---------5

1=====

2=====

3=====

2+ 光标下移2行,即数据文件二的第一行置为当前行

|--------1---------2---------3---------4---------5

1-----

2-----

3-----

!!!!!!!!!!!!!!!!!!!!!!!!

|--------1---------2---------3---------4---------5

1=====

2=====

3=====

:.m'a^M 把数据文件二的第一行移至标记行的下方

|--------1---------2---------3---------4---------5

1-----

1=====

2-----

3-----

!!!!!!!!!!!!!!!!!!!!!!!!

|--------1---------2---------3---------4---------5

2=====

3=====

+ 光标下移一行,即数据文件一的第二行置为当前行

|--------1---------2---------3---------4---------5

1-----

1=====

2-----

3-----

!!!!!!!!!!!!!!!!!!!!!!!!

|--------1---------2---------3---------4---------5

2=====

3=====

= 这一步很关键,是典型的递归调用,重复完成以上步骤

例四、在文件中置入行号

工作中,我们有时希望把行号置入文件中,而VIM提供的功能 :set nu 只能显示行号,不能编辑或将其置入文件当中,下面的宏命令脚本row_num.vim可以完成此项功能。

"------------------------------------------

"Macro Function : Source File Add Row_Num

" Date : 2001/12/01

" Author : Yan Shi

"------------------------------------------

:%s/^/^I/

:$

:let end=line(".")

:1

"------------------------------------------

:let num=1

:while num<=end

:let line=getline(".")

:let temp=substitute(line,$,num,"")

:call setline(".",temp)

:+

:let num=num+1

:endwhile

"------------------------------------------

请注意:本例中的^I表示键盘上的TAB键,并非^和I两个字符。下面,我针对该宏命令脚本逐一讲解。

:%s/^/^I/ 每一行的行首添加一个TAB字符

:$ 到文件的末行

:let end=line(".") 末行的行号 ==〉变量 END,函数line的功能是取得指定行的行号,此处参数"."表示当前行

:1 到文件的首行

"------------------------------------------

:let num=1 1 ==〉计数器

:while num<=end

:let line=getline(".") 取当前行的内容 ==〉变量 LINE

:let line=substitute(line,$,num,"") 在变量 LINE 的前面置入行号

:call setline(".",line) 将变量 LINE 的内容写回当前行

:+ 下移一行

:let num=num+1 计数器加一

:endwhile 循环执行,直到文件结束

"------------------------------------------

有关正则表达式的使用

UNIX/LINUX下的很多工具之所以强大、灵活,关键是因为有了正则文法和元字符,这也是VIM乃至UNIX/LINUX系统的精华所在。正因为使 用灵活,因此掌握起来比较吃力,如果不是真正理解,实际运用中会出现千奇百怪的错误。因此,有必要对这部分知识多花些气力。下面结合具体实例讲解。

例五、有一文件,包含某外企的中国员工的资料,首先是姓名,然后是两个空格,其次是15位身份证号码。

zhang.fei 430759701022003

diao.chan 651302801225012

guan.yu 342869680413001

xi.shi 120638780214006

liu.bei 210324650708001

现在,有以下问题需要解决:

按照外国人的习惯,应该是名在前,姓在后。因此,文件中的姓名字段需要修改。

姓与名的首字母应该大写。

根据身份证号码,还可以判断出生年月日,将其作为一个新字段添加。

根据身份证号码,可以判断出性别。若为男性,添加male,若为女性,添加female 。

将男女员工分开,男员工在前,女员工在后。

将各字段数据左对齐

最终结果如下:

Fei.Zhang 430759701022003 1970/10/22 male

Yu.Guan 342869680413001 1968/04/13 male

Bei.Liu 210324650708001 1965/07/08 male

-----------------------------------------------

Chan.Diao 651302801225012 1980/12/25 female

Shi.Xi 120638780214006 1978/02/14 female

为了完成上述功能,只需执行脚本employee.vim ,使用方法为 :so employee.vim 回车即可。

脚本内容如下:

:%s/ / /

:%s/\(............\)\( *\)/\1/

:%s/\([A-Za-z][A-Za-z]*\)\(\.\)\([A-Za-z][A-Za-z]*\)/\u\3\2\u\1/

:%s/$/ xxxxxx/

:%s/\([0-9]\{6}\)\([0-9]\{6}\)\([0-9]\{3}\) \(xxxxxx\)/\1\2\3 \2/

:%s/\(..\)\(..\)\(..\)$/19\1\/\2\/\3

:%s/$/ xxxxxx/

:%s/\([0-9]\{14}[13579]\)\(.*\)\(xxxxxx\)/\1\2male /

:%s/\([0-9]\{14}[02468]\)\(.*\)\(xxxxxx\)/\1\2female/

:$

:s/.*/&^M-----------------------------------------------

:g/female/.m$

在这个脚本中,使用了大量的正则表达式,这里仅对涉及到的正则表达式做一简要介绍。有关正则表达式的内容相当多,本文不可能占用大量篇幅叙述,请大家谅解。

% 地址范围符号,代表文件中的所有行,作用等同于地址范围 1,$

. 与任意单字符(换行符除外)匹配,例如 y.s 可以匹配 yas y.s 或 y s 等等。

* 与前一字符的0次或多次出现匹配,例如 y*s 可以匹配 yys yyyyys 或 s 等等。

$ 与行尾匹配。

& 代表模式匹配中出现的字符串,例如 s/abc/&def 是把当前行的abc替换成abcdef 。

[] 匹配[]中出现的字符,例如[abc]匹配字符 a,b 或 c ,[a-zA-Z]匹配所有的英文字符。

\( \) \(和\)之间出现的内容可以由\num来替代。

\1\2\3 替代\(和\)之间出现的内容。

\u 将后续字符串的首字母大写。

\{num} 与前一字符的num次出现匹配。

现在,我们对脚本逐条讲解,希望能帮助大家理解正则文法。

⑴:%s/ / /

将文件中每行出现的2个空格替换为10个空格。

zhang.fei 430759701022003

diao.chan 651302801225012

guan.yu 342869680413001

xi.shi 120638780214006

liu.bei 210324650708001

⑵:%s/\(............\)\( *\)/\1/

保留行首的12个字符,将其余的空格删除,这样,前两个字段就对齐了。

zhang.fei 430759701022003

diao.chan 651302801225012

guan.yu 342869680413001

xi.shi 120638780214006

liu.bei 210324650708001

⑶:%s/\([A-Za-z][A-Za-z]*\)\(\.\)\([A-Za-z][A-Za-z]*\)/\u\3\2\u\1/

将文件中每行出现的雇员姓名互换,并将首字母大写。

Fei.Zhang 430759701022003

Chan.Diao 651302801225012

Yu.Guan 342869680413001

Shi.Xi 120638780214006

Bei.Liu 210324650708001

⑷:%s/$/ xxxxxx/

在每一行的行尾添加2个空格和6个x

Fei.Zhang 430759701022003 xxxxxx

Chan.Diao 651302801225012 xxxxxx

Yu.Guan 342869680413001 xxxxxx

Shi.Xi 120638780214006 xxxxxx

Bei.Liu 210324650708001 xxxxxx

⑸:%s/\([0-9]\{6}\)\([0-9]\{6}\)\([0-9]\{3}\) \(xxxxxx\)/\1\2\3 \2/

将xxxxxx替换成出生年月日。

Fei.Zhang 430759701022003 701022

Chan.Diao 651302801225012 801225

Yu.Guan 342869680413001 680413

Shi.Xi 120638780214006 780214

Bei.Liu 210324650708001 650708

⑹:%s/\(..\)\(..\)\(..\)$/19\1\/\2\/\3

将年月日用/字符分隔,并在年前添加19。

Fei.Zhang 430759701022003 1970/10/22

Chan.Diao 651302801225012 1980/12/25

Yu.Guan 342869680413001 1968/04/13

Shi.Xi 120638780214006 1978/02/14

Bei.Liu 210324650708001 1965/07/08

⑺:%s/$/ xxxxxx/

在每一行的行尾添加2个空格和6个x

Fei.Zhang 430759701022003 1970/10/22 xxxxxx

Chan.Diao 651302801225012 1980/12/25 xxxxxx

Yu.Guan 342869680413001 1968/04/13 xxxxxx

Shi.Xi 120638780214006 1978/02/14 xxxxxx

Bei.Liu 210324650708001 1965/07/08 xxxxxx

⑻:%s/\([0-9]\{14}[13579]\)\(.*\)\(xxxxxx\)/\1\2male /

身份证号码末位是奇数的,将xxxxxx替换成male

Fei.Zhang 430759701022003 1970/10/22 male

Chan.Diao 651302801225012 1980/12/25 xxxxxx

Yu.Guan 342869680413001 1968/04/13 male

Shi.Xi 120638780214006 1978/02/14 xxxxxx

Bei.Liu 210324650708001 1965/07/08 male

⑼:%s/\([0-9]\{14}[02468]\)\(.*\)\(xxxxxx\)/\1\2female/

身份证号码末位是偶数的,将xxxxxx替换成female

Fei.Zhang 430759701022003 1970/10/22 male

Chan.Diao 651302801225012 1980/12/25 female

Yu.Guan 342869680413001 1968/04/13 male

Shi.Xi 120638780214006 1978/02/14 female

Bei.Liu 210324650708001 1965/07/08 male

⑽:$ 到文件的最后一行

⑾:s/.*/&^M-----------------------------------------------

在文件的最末行插入一行 "-" 字符。

Fei.Zhang 430759701022003 1970/10/22 male

Chan.Diao 651302801225012 1980/12/25 female

Yu.Guan 342869680413001 1968/04/13 male

Shi.Xi 120638780214006 1978/02/14 female

Bei.Liu 210324650708001 1965/07/08 male

-----------------------------------------------

⑿:g/female/.m$

将所有的女员工记录移至文件尾。

Fei.Zhang 430759701022003 1970/10/22 male

Yu.Guan 342869680413001 1968/04/13 male

Bei.Liu 210324650708001 1965/07/08 male

-----------------------------------------------

Chan.Diao 651302801225012 1980/12/25 female

Shi.Xi 120638780214006 1978/02/14 female

笔者目前正在为某外资公司从事大型机(IBM S/390)的软件开发,一切工作都在TSO环境中进行。为了对编写的程序进行测试,必须准备测试数据。有过大型机开发经验的人会知道,通过TSO,输入 字符型数据还可以,如果要输入16进制数据,操作起来很麻烦。因为16进制数是纵向排列的,输入时既不方便,又很容易错位。怎么解决呢?我尝试了几种办 法,实际证明,用VIM最方便。

例六、下列数据 1234567890ABCDEF ,将其变成 13579ACE 24680BDF 的形式,这样,数据就可以很方便的粘贴到TSO环境中了。

下面给出宏命令脚本change_d.vim

"----------------------------------------------------

"Macro Function : Convert Char Arrange Direction

"

" Sample : 40 50 60 ==> 4 5 6

" 0 0 0

" Date : 2001/12/01

" Author : Yan Shi

"----------------------------------------------------

:s/.*/&^M/

:1

:map = malx+$p-`al=

说明如下:

⑴ :s/.*/&^M/ 在数据行下方添加一空行。

⑵ :1 回到文件的首行的首字符。

⑶ :map = malx+$p-`al= 将一大串VIM命令映像给字符=

① ma 将首字符标记为a

② l 光标右移一个字符

③ x 删除光标处字符

④ + 移至下一行

⑤ $ 到行尾

⑥ p 将删除的字符粘贴

⑦ - 回至上一行

⑧ `a 返回到标记字符处

⑨ l 光标右移一个字符

⑩ = 递归调用,重复以上步骤,直到将该行所有的数据处理完。