学习完第二章,小结一下。
-----------------------------------------------
第一章补充:区别变量的取消和清空,取消会释放变量的内存空间,使用unset命令,如unset var;而清空就是置为NULL,如var=;
-----------------------------------------------
第二章内容开始~
目录
1,常用也重要的几个命令
2,cat命令
3,录制和回放终端上的会话
4,find命令
5,xargs命令
6,tr命令
7,校验与核实命令
8,排序、单一与重复
9,临时文件名与随机数
10,文件分割
11,根据扩展名切分文件名 -- 本质就是变量内容的删除和取代
12,重命名和移动,rename mv命令
13,拼写检查和字典操作
14,交互输入自动化
1,常用也重要的几个命令
grep awk sed find,在本章和后面章节会学习到;
2,cat命令
cat,我们都知道是查看文件内容的命令;
2.1 cat本身表示concatenate(拼接),用例:
cat file1 file2 ….或
cmd1 | cat – file1.... (将stdout和文档拼接)
2.2 可用选项
cat –s file,压缩空白行(-s suppress repeated empty output lines)
对比,tr –s ‘\n’,仅保留一个\n(效果和cat –s file不同,一个是除了空白行,另一个是除了换行符),如
原:a | cat–s file结果:a | tr–s ‘\n’结果:a
| | A
| A |
A | |
cat –T file,将制表符(\t)显示为^I
cat –n file,显示行号
3,录制和回放终端上的会话
这里说的会话即执行的那些命令;需要使用script和scriptreplay这两工具;
3.1 基本用法
script –t 2> timing.log –a output #解释:timing.log文件存储时序信息,output 文件存储命令输出,
开始输命令… # -t用于将时序数据导入stderr
exit(或ctrl+D)
-------------------------------上面是录制,下面是回放
scriptreplay timing.log output #解释:会按照原来的时间和内容播放
另:尝试直接 script>timing.log –a output不对;
尝试直接 script (默认放在一个typescript文件终)或script output,发现保存在文件里的内容不对
还不清楚怎么回事;
3.2 一个很好的使用方式,可以实现一个终端输入,其它终端同步查看该输入过程:
1)打开两终端,terminal1 terminal2;
2)terminal1中,mkfifo scriptfifo,建立fifo;
3)terminal2中,cat scriptfifo,从fifo中获取输入;
4)terminal1中,script –f scriptfifo
输入其它命令,此时terminal2会同步显示
script -f, --flush
Flush output after each write. This is nice for telecooperation: oneperson does
`mkfifo foo; script -f foo', and another can supervise real-time what isbeing done
using `cat foo'.
原理,terminal1和terminal2通过fifo建立起连接,可以通过各种方式通信,这里用script –f只是能够不断的将各行输入内容导入到fifo文件中,直到exit退出;而如用echo aaa>scriptfifo,就只会通信一次后结束;
4,find命令
4.1 基本使用
find 路径,列出路径(及子目录)下所有文件及目录;
find 路径 –print,pint将结果打印到屏幕上,但这个动作是预设动作;
find 路径 –print0,print以’\n’分隔找到的文件名,而print0以’\0’即NULL作为分隔符(当文件名中含有’\n’符号时将起重要作用);
4.2 各种条件下的查找
-name,指定文件名,例find . –name “*.txt”
-iname,忽略字母大小写
-o,或操作,例find . –name aa –o –name bb或find . \( -name aa –o –name bb \),注意()处要有空格
-path,可以使用通配符来匹配文件路径或文件,注与name区别是可以指示路径,用法与name类似;
-regex,与path类似,不同是regex基于正则表达式来匹配文件路径;
-iregex,忽略大小写的regex;
否定参数用”!”,例,find . ! –name “*.txt”;(也可以find后用grep -v反选,不过效率没有这么高吧)
-maxdepth,最大深度,例 find . –maxdepth level –type f,最深level层;
-mindepth,最小深度,例 find . –mindexpth level –name aa,最浅level层;
注,maxdepth和mindepth放在第3个参数较好,放在第4参数及后面可能会影响查找效率;
-type,根据文件类型过滤:f文件、l符号链接、d目录、c字符设备、b块设备、s套接字、p fifo;
-atime,访问时间,单位为天,数值上带-、+或不带符号,下同
-mtime,修改时间
-ctime,状态变化时间
例子:find . –nameaa –mtime -7:最近7天内的
find. –name aa –mtime 7:第7天前的
find. –name aa –mtime +7:超过7天之前的
另,有类似的-amin、-mmin、-cmin,以分钟为基本单位,其他同atime、mtime、ctime
-newer,比参考文件更新的文件,例,find . –type f –newer referfile
-size,基于文件大小,例:
find . –type f –size +2k,大于2kb的文件(单位:b块/512字节,c字节,w字,k、M、G,下同)
find . –type f –size -2k,小于2kb的文件
find . –type f –size 2k,等于2kb的文件
-delete,删除找到的文件,例,find . –name aa –delete
-perm,基于文件权限找,例,find . –type f –perm 644
-user USER,基于所有权,例,find . –type f –user root(USER可以是用户名或UID)
-exec,find借助exec与其他命令结合一起运行,例如:
find . –type f –exec cat {} \; #解释,cat后的{}会被替换为找到的文件名,即会执行cat file1; cat file2等类似操作;
#另分号表示参数的结束,be arguments to the command until an
# argument consisting of `;' isencountered
注,exec后可接一个脚本,这样就可以执行一系列命令,否则只能执行单一命令;
-prune,用于排除目录,if the file is a directory, do not descend into it;例,
find . –name “.svn” –prune,将不会查找.svn目录下的内容;
另,也常用find . |grep –v .svn来反选.svn目录,效率应该比直接用prune差,但grep –v可以反选任何文件,不仅是目录
5,xargs命令
5.1 基本用法
xargs擅长将标准输入数据转换成命令行参数;
(这样,一些命令只能接受命令行参数而无法接受stdin,就可以利用xargs获取stdin上的数据了)
例:
ls | xargs grep “stdout”,在文件内部查”stdout”;
cat file | xargs,会把file中的换行符换成空格哦,见下面说明;
5.2 可用选项
none,什么都不用,xargs会用空格替换掉换行符(即多行变单行了),例:
cat file,结果
1 2 3
4
cat file | xargs,结果
1 2 3 4
-n N,单行变多行,把stdin变为多行,每行N个参数,例,
cat file,结果
1 2 3
4
cat file | xargs –n 2,结果
1 2
3 4
-d,为输入指定一个定制的定界符,例
echo “asdX123Xfgh” | xargs –d X,结果
asd 123 fgh
-I,指定一个替换字符串,该字符串在xargs扩展时被替换掉,还是看例子吧:
首先,xargs已经能够将stdin的数据作为参数给xargs后面的命令了,如 find . | xargs grep “aa”,
现在,有一个需求如下,某cmd有固定的参数格式为cmd –p arg –l,其中只有arg是从stdin读入的数据,此时就可以使用-I选项了,例:
cat file | xargs –I {} cmd –p {} –l
解释,-I后面的{}将被xargs获取的参数所代替(注,实验显示{}大括号可以被其它任何字符串代替),这样cmd –p {} –l中的{}也就会变为相应的参数了(注,对每一个参数,cmd命令都执行一次)
5.3 相关使用实例
1)find和xargs常常搭配使用,如 find . | xargs rm –f
上面语句其实存在危险,由于find的输出结果的定界符可能是’\n’或空格,而某些文件名就包含这些符号,这样便有可能导致rm误删,改进的命令为:
find . –print0 | xargs -0 rm –f,建议find和xargs搭配时,用print0来输出,此时以null为分隔输出;而xargs -0是将\0(NULL)作为输入定界符!
2)xargs不能为多组命令提供参数,一种其他的实现方式为使用子shell和while,例如:
cat file | (while read arg; do some cmd;done)
解释,使用while用于一个一个读参数,类似于xargs部分功能;
使用子shell(some cmd)则是用于运行命令(且可以是多个命令),此为xargs的另一部分功能;
6,tr命令
tr, translate,转换工具
6.1 基础使用
首先,注意,tr只能从stdin获取数据!
格式为 tr [option] set1 set2
set1和set2为两个字符或字符集合;tr将stdin中的字符从set1映射到set2;
看实例最好懂:
echo “helloIS WHo” | tr ‘A-Z’ ‘a-z’,结果为”hello is who”;
cat file | tr ‘\t’ ‘ ’,将制表符变为空格;
注,若set1长于set2,则set2会重复其最后一个字符,直到长度等于set1的;
若set1短于set2,则set2多余的部分会被忽略;实例如下:
echo "ABCDEFG" | tr 'A-G' 'a-b' ,结果abbbbbb
echo "ABCDEFG" | tr 'A-B' 'a-g' ,结果abCDEFG
注2:一些字符集合
alnum 字母和数字
alpha 字母
cntrl 控制(非打印)字符
digit 数字
gragh图形字符
lower 小写字母
print 可打印字符
punct 标点符号
space 空白字符
upper 大写字母
xdigit 十六进制字符
例:echo"asd 34 sss" | tr '[:lower:]' '[:upper:]' 结果”ASD 34 SSS”
6.2 可用选项
-d,指定要删除的字符集合,例:
echo “hello 123 asd 345” | tr –d ‘0-9’,结果”hello asd”
-c [set],取set集合的补集,例:
echo “hell 23” | tr –d –c ‘0-9 \n’,结果” 23”,即删除除0-9及空格及换行符的其他字符;
-s,压缩重复的字符为单一字符,例:
Echo “asd 123” | tr –s ‘ ’,结果 ”asd 123”;
7,校验与核实命令
校验即从文件生成校验和秘钥;主要介绍了两个工具md5sum和sha1sum,分别对了MD5、SHA1两种算法;
基本使用:
1)生成校验和
例:md5sum filename
结果e5828c564f71fea3a12dde8bd5d27063 filename
或md5sum filename > file_sum.md5,此后就可以利用该md5文件来核实文件的完整性了;
另md5sum file1file2…
结果会为
[checksum1] file1
[checksum2] file2…
即每行对应一个文件及其校验和
2)核实
例:md5sum –c file_sum.md5,就用-c(check)选项来核实;
结果可能为filename:OK
3)对应SHA1算法,使用方式与MD5算法相似,只需修改命令为sha1sum;
8,排序、单一与重复
8.1 排序命令 sort
1)基本使用:
sort file1 file2 …,将所有文件的内容按字母排序后输出到stdout;
sort file1 file2 … > sortedfile,同上,不过是将排序后的内容输出到文件中;
sort file file … -o sortedfile,同上,-o指明将结果写到某个文件中(可以是某待排序文件自身);
cat file | sort …,从stdin获取数据然后排序;
2)可用选项
-n,按数字进行排序;
这里要注意一下,如果我们要按数字大小排序,务必加上-n参数,否则按照字符串顺序的话容易出现错误,如下例:
$cat aa
100
01000
$sort aa #按字符串顺序排序的结果
01000
100
$sort -n aa #按数字大小排序的结果,即100 < 1000
100
01000
-r,按逆序排序,reverse;
-R,随机排序,random;
-M,按月份排序;
-d,按字典顺序排序;
-f,忽略大小写;
-b,忽略文件中的前导空白字符;
-u,uniq,重复的行只显示一行,如下
$cat aa
aa
dd
cc
aa
cc
$sort -u aa
aa
cc
dd
-c,-C,check,检查数据是否已排序,-c会输出未排序的提示信息,而-C无输出,但-c和-C的结果都可以通过echo $?得到,如:
sort –C file
if [ $? –eq 0 ]; then
echo sorted;
else
echo unsorted;
fi
-m file1 file2,将两个文件进行归并排序,所以两个文件最好是已排好序的,这样merge的结果也是有序的;
-k,指定了排序按哪一个键(key)来进行,键也即列号,
-t,分隔符,默认是空白符,
-k、-t 的使用如下例:
$cat aa
1 mm 2000
2 ff 1000
3 pp 3000
$sort -nk 3 aa #注,以第三列为键,且按数字大小排序;
2 ff 1000
1 mm 2000
3 pp 3000
$ cat aa
1:mm:2000
2:ff:1000
3:pp:3000
$ sort -t ':' -k 3 –n aa
2:ff:1000
1:mm:2000
3:pp:3000
8.2 单一与重复命令uniq
1)基本使用
uniq用于消除重复的行,它仅比较相邻的行,所以uniq最好用在排序好的数据上,如下例:
$ cat aa
a
b
b
c
$ uniq aa
a
b
c
但,假如用于未排序好的数据下,有:
$ cat aa
a
b
b
a
$ uniq aa
a
b
a
2)可用选项
-u,仅显示不重复的行,如
$ cat aa
a
b
b
c
c
$ uniq -u aa
a
-d,仅显示重复的行,如
$ uniq -d aa
b
c
-c,统计各行出现的次数,如
$ uniq -c aa
1 a
2 b
2 c
-s,指定可以跳过前N个字符;
-w,指定用于比较的最大字符数;这两者可用于uniq的索引;例:catfile | uniq –s 2 –w 2,即指定第3-4字符为索引;
-z,生成包含0值字节终止符的输出;这个我使用起来不太对;
***一个使用例子:一个包含重复字符的字符串,如何将不同的字符找出,并在其前面打出其重复的次数,如,
输入:ahebhaaa
输出:4a1b1e2h
命令:
IN="ahebhaaa"
echo $IN
OUTPUT=$(echo${IN} | sed 's/[^.]/&\n/g' | sed '/^$/d' | sort | uniq -c | tr -d ' \n')
echo $OUTPUT
结果:
ahebhaaa
4a1b1e2h
解析:sed 's/[^.]/&\n/g',在每个字符后加一个换行符,&表示替换前对应的字符串;[^.]表示一个字符?这个不太清楚;sed ’/^$/d’,删除空白行(前一步会将数据最后加上一个空白行);sort,排序;uniq –c,单一化并进行统计;tr –d ’ \n’,删除空格和换行符,得到最终结果。
9,临时文件名与随机数
1)tempfile,生成一个临时文件,同时打印出其名字,如
$ tempfile
/tmp/filejcp6tL #总是在tmp目录下
2)随机数变量 $RANDOM,使用如
tempfile=“/tmp/tmp-$RANDOM“
3)另一常用文件起名方式:
tempfile=”/tmp/var.$$”
$$为当前运行进程的进程ID
10,文件分割
10.1 先看一个生成文件的命令dd
基本用法,
dd if=”input_file” of=”output_file” bs=”block_size”count=”number”
解释,if表示数据输入源文件;of表示数据输出的文件;
bs表示一个block的大小,默认512kb;count表示多少个block;
注:该命令也常常用于备份!
例子:生成一个100kb的测试文件,
dd if=/dev/zero of=data.file bs=100k count=1
10.2 分割命令split
1)基本使用:
split –b 10k data.file
结果生成 xaa xab…等10k大小文件;
split –b 10k data.file –d –a 4
结果生成x0001 x0002…等文件;
参数解释:-b,--bytes=SIZE, put SIZE bytes per output file,单位可以为k、M、G、c(byte)、w(word)
-d,文件名以数字为后缀;-a,指定后缀的长度(数字和字符后缀都适用)
2)其它选项
a,前缀名,默认的前缀名为”x”,可以在split的最后一个参数(即PREFIX)上指定前缀名,如
split –b 50k data.file MYNAME
结果生成MYNAMEaa MYNAMEab
b,按行数分割,之前都是-b按大小分割,用-l进行按行分割,如
split –l 10 data.file
c,另一个更强大的分割工具csplit,可以按单词或文本内容进行分割,这个命令感觉更少用,参数也较多,使用到时再查吧…
11,根据扩展名切分文件名 -- 本质就是变量内容的删除和取代
参考鸟哥书上的这块内容,有结论:
${变量#关键词} :将变量中从左到右符合关键词的最短数据删除;常用于删前缀
${变量##关键词} :将变量中从左到右符合关键词的最长数据删除;常用于删前缀
${变量%关键词} :将变量中从右到左符合关键词的最短数据删除;常用于删后缀
${变量%%关键词} :将变量中从右到左符合关键词的最长数据删除;常用于删后缀
${变量/旧字符串/新字符串}:将变量中第一个旧字符串替换为新字符串;
${变量//旧字符串/新字符串}:将变量中所有的旧字符串替换为新字符串;
看例子吧:
$ echo ${URL}
www.www.google.com
$ echo ${URL#*.} #删短前缀
www.google.com
$ echo${URL##*.} #删长前缀
com
$ echo${URL%.*} #删短后缀
www.www.google
$ echo${URL%%.*} #删长后缀
www
$ echo${URL/www/WWW} #替换第一个旧字符串
WWW.www.google.com
$ echo${URL//www/WWW} #替换所有旧字符串
WWW.WWW.google.com
12,重命名和移动,rename mv命令
mv命令可以移动文件和重命名文件,但每次仅处理单个文件;不过也可以搭配其它语句来实现批量处理;
rename命令则可以批量重命名文件;
基本使用:
1)mv file_name1 file_name2,如果file_name1和file_name2在同一目录,则起到重命名左右,否则为移动文件作用;
2)rename,分c语言版和perl版,我的ubuntu上是perl版,据说比较老的系统上才是c语言版;perl版的使用格式如下,
rename [ -v] [ -n ] [ -f ] perlexpr [ files ]
有两个主要参数,perlexpr为perl表达式,指明要做怎样的修改;files指明哪些文件要做修改;
Perl语言没学过,仅列出下面两例子:
$ ls
a.jpg b.jpg
$ rename 's/jpg/JPG/g' * #类似与sed中的字符替换,*表示对所有文件做处理
$ ls
a.JPG b.JPG
$ rename 'y/A-Z/a-z/' *
$ ls
a.jpg b.jpg
13,拼写检查和字典操作
1) linux系统中有一些字典文件,如
$ ls /usr/share/dict/
british-english american-english
这些文件就是一行一行的单词,包含了所有合法的单词;可以通过查看某个字符串是否在该字典文件中来判断该字符串是否拼写正确;例如:
$ grep “^$word$” /usr/share/dict/*-english –q #”^$word$”表示仅包含该单词;grep –q表示不输出任何信息
$ echo $? #此时结果能通过$?来查看
2)另有一个与语法相关的命令为aspell,其中一个用法为,
$ echo "asd" | aspell list
asd #拼写错误则结果为字符串,aspell list - Produce a list ofmisspelled words from standard input.
$ echo "hello" | aspell list
#拼写无误则结果为空
3)查找某单词
最常用为使用grep,如
$ grep “^word” file,查找file中以”word”开头的句子;
另还有一个命令,look -- display lines beginning with a given string,使用如下:
$ look word file,这里look就是找以word开头的句子;没有file参数时,默认查找字典/usr/share/dict/words(最终也是link到/usr/share/dict/*-english);
14,交互输入自动化
1)交互输入使用read,但现在要自动化,即输入方将所有参数自动输入给处理后台,而不是一个参数一个参数的手动输入。有以下方式实现:
$ echo –e “1\nhello\n” | cmd1
echo -e,enable interpretation of backslash escapes,即使能下划线;
-E,disable interpretation of backslash escapes (default)
或 $ echo –e “1\nhello\n” > input.data
$ cmd1 < input.data
2)另外还有一个工具expect,可以实现动态输入,即输入的参数不需要按照顺序提供给后台处理程序;该工具一般得自己安装;使用用例如下:
#!/usr/bin/expect
spawn./cmd.sh 指定需自动化哪一个脚本;
expect “enternumer:” 指示等待的消息;
send “1\n” 指示对应上面的待定消息,要发送的消息;
expect “entername:” 同上上;
send “hello\n” 同上上;
expect eof 指明命令交互结束;