首先恭喜你,看了这个文章,推荐两本书,linux shell 脚本攻略, shell脚本学习指南 ^_^ 。免积分下载地址为:http://download.csdn.net/detail/vsooda/5583263
shell脚本学习指南大概很多人都看过,但是看完之后对于shell能干什么,可能并不十分清楚,而linux shell 脚本攻略则以一个个任务的形式,用脚本解决。 而且有详细的解释。相当于cookbook。包含了各个方面,基础的,网络的,系统管理的。但是对于基础知识的介绍,可能需要读者查看相关书籍,所以shell脚本学习指南可以拿来翻翻。
以下是个人的一点粗浅认识,不一定对。
关于shell
lilnux与windows不同之处在于提供了很多工具。而且多个命令之间用管道|连接,可以实现一系列任务,这在windows应用程序界限很明显的地方是很难实现的。
linux的shell提供了很多工具。工具就相当于函数,但是与我们编程语言的函数不同在于,并不需要写一个入口函数来调用它,而多个工具可以一起使用。
find,sed,awk,grep等命令都可以称为工具。
find 查找
grep 也是查找
sed 可以实现一些替换等
awk 相当与编程语言,在awk ' '包含里面进行简单编码,实现相应的功能
还有很多工具,具体要查看书籍。
而一行一行的命令不适合批处理,不适应管理自动化。所以需要脚本。
脚本就是把一堆命令写在一起。在#!/bin/bash 指明这是个脚本。具体参见书籍。
关于linux shell 脚本攻略
前面几章介绍基础知识,以及应用。后面的对于网路的操作,引入了curl,wget,利用了服务提供商的rss feed。其它的与前面的编程一样,都是文本替换啥的。(这里显示出shell的好用之处,不必专门写一个程序来操作,不用自己写很多函数,且多个操作结合方便,灵活)。后面介绍了归档,压缩,加密工具。最后两章是一些系统运维的知识,查看系统磁盘状态,查看进程使用cpu的情况等等。要用的时候细看。
看了很久了,有点忘记了,以后看书,再详细记录一些知识点。现在都忘光了。提供一个方向罢。
p130 \(pattern\) 用于匹配字符串
\1 代表匹配到的第一个子串 后向引用
\(\)对结果进行分组,利于后向引用
p26 使用反引用或者$()来存储命令,如cmd_output =$(ls | cat -n) 或者 cmd_output=`ls | cat -n`
------------ update 2013.6.22
把前几章的基础知识梳理了一下。
可以将.加入系统路径,那么在执行的时候就不需要./
PATH=$PATH:.
命令
grep awk sed find
cat
find是linux工具箱中最棒的工具之一。
1. 根据文件名或正则表达式来匹配搜索 -name -iname忽略大小写,OR, -path可以使用使用通配符来匹配文件或者路径。-regex与-path类似,不过是使用正则表达式来匹配。
2. 否定参数 !
3. 使用-maxdepth,mindepth来指定遍历目录深度
4. 根据文件类型进行搜索 -type (f, l, d, c, b, s, p)
5. 根据时间进行搜索
6. 基于文件大小的搜索。 find . -type f -size +2k
7. 删除匹配文件 -delete
8. 基于文件权限和所有权的匹配 find . -type f -perm 644 -print //打印出权限为664的文件
9. 结合find执行命令或动作 find命令可以借助选项-exec与其他命令进行结合。-exec算得上find最强大的特性之一。-exec {} \;一起使用
10. 让find跳过制定目录
find sourcepath \( -name ".git" -prune \) -o \( -type f -print \)
-name "git" -prune 将sourcepath下git目录中的文件排除。后面半句进行显示。
xargs xargs命令把从stdin接收到的数据重新格式化,再将其作为参数提供给其他命令。
tr tr可以对来自标准输入的字符进行替换,删除和压缩。它可以将一组字符串变成另一组,因此称为转换指令。(translate)
(1)echo “HELLO WHO IS THIS” | tr "A-Z' 'a-z' 将大写转化为小写
(2) 用tr删除字符 -d cat file.txt | tr -d '0-9' 将数字去掉(p50)
echo hello 1 char 2 next 4 | tr -d -c '0-9 \n' 输出 1 2 4
(3) 用tr压缩字符 例如压缩空白字符 cat file.txt | tr -s ' '
(4) 字符类
sort
排序 -n数字, -r逆序,-C判断是否已排序, -m对已排序的合并,-k指定按照哪个键进行排序(第几列)如:sort -nrk 1 data.txt 根据第一列一数字方式逆序排序
-b用于忽略前导空白,-d用于指明以字典序排序。
uniq消除重复内容
-d找出重复的内容,-c统计出现次数,-s跳过前面n个字符,-w比较字符数
-z生成包含0值终止符的输出
OUTPUT=` echo $INPUT | sed 's/[^\n]/&\n/g' | sed '/^$/d' | sort | uniq -c | tr -d ' \n'`
Input: ahebhaaa
Output: 4a1b1e2h
INPUT= "ahebhaaa"
OUTPUT=` echo $INPUT | sed 's/[^\n]/&\n/g' | sed '/^$/d' | sort | uniq
-c | tr -d ' \n'`
echo $OUTPUT
split分割文件
split -l 1 data.txt -d -a 2 hidfa
每个文件一行,-d以数字编号,-a后缀长度
-b每个文件块大小
分割文件名和扩展名
分割文件名使用% 从右向左匹配
扩展名使用# 从左向右匹配
%%,##贪婪匹配
file_jpg="sample.jpg"
name=${file_jpg%.*} //文件名 sample
extension=${file_jpg#*.} //后缀名 jpg
Chapter 01,Chapter 02,Chapter 03,Chapter 04,Chapter 05的重命名可以使用一下脚本
#!/bin/bash count=1; for item in Chapter* do new=c${item##* } mv "$item" "$new" 2>/dev/null if [ $? -eq 0 ]; then echo "Renaming $img to $new" let count++ fi done
交互输入,expect等。
第三章 file in file out
使用dd生成任意大小的文件
dd if=/dev/zero of=junk.data bs=1M count=1
if表示input file。of表示output file
集合操作。comm找出两个文件中相同部分
p101例子有点问题
创建长路径 mkdir -p /home/slynux/test/hello/child
权限 rwx, chmod u+x filename, chmod 777 filename
setuid,setgid,粘滞位。
user,group,other 分别有一个x,第一,二个x设置为S,分别表示setuid,setgid。表示其它用户(组)在执行带有S的文件,等同于所有者(组)的权限。而目录有一个特殊的权限位为粘滞位t.设置了粘滞位表示非所有者不能删除目录。
修改所有者 chown user.group filename
chattr 不可修改
touch 用于生成空白文件
创建符号链接(linux的符号链接类似于windows的快捷方式)
ln -s target symbolic_link_name
eg: ln -s /var/www/ ~/web 在home目录中创建一个指向/var/www的符号链接。
有的时候用sh不行,用/bin/bash却可以。但是明明sh指向的链接是/bin/bash啊。为啥?
bash的参数
$0 返回值
$1 第一个参数
$2 第二个参数
$@ 被扩展为 "$1" "$2" "$3" (用得最多)
$* 被扩展为 "$1c$2c$3"
$#表示参数个数
找不同之处,以及升级补丁。。
diff version1.txt version2.txt
diff -u version1.txt version2.txt
diff -u version1.txt version2.txt > version.patch ---> patch -p1 version1.txt < version.patch
head tail 求开始记录,结束记录
pushd popd 对目录进行压栈,这样可以在多个目录之间切换
wc用于统计字符数
tree命令是以图形化的树状结构打印文件和目录的主角。
第四章 让文本飞
正则表达式
.匹配任意字符
grep 用于文本搜索,返回的是搜索结果的文本行, 若要只输出匹配部分,则需要使用-o
grep match_pattern filename
如果要使用正则表达式,则要加上-E
echo this is a line. | grep -o -E "[a-z]+\." 因为.在正则表达式中有特殊含义,所以需要转义
-v逆转, -c匹配行数
grep "test_function()" . -R -n 这是开发人员使用最多的命令之一。用于查找某些文本位于那些源码文件中
忽略大小写 -i
匹配多个样式 -e
文件指定多个样式,使用-f指定文件
包括 排除 --include --exclude.. grep "main()" . -r --exclude "README"
使用0值字节后缀(以\0结束)的grep和xargs
-q静默输出
-A显示之后几行,-B之前。 -C前后
cut是一个帮我们将文本按列进行切分的小工具,它也可以指定分割每列的分界符
命令格式:cut -f FILED_LIST filename eg: cut -f 2,4 filename. 打印2,4列,如果奥打印2到4列则相应改为2-4。打印前两个字段则,可以 -f -2
-d 指定定界符
--complement 补集
指定输出定界符 --output-delimiter 如cut range_fields.txt -c1-3,6-9 --output-delimiter ","
-b表示字节,-c表示字符,-f表示字段
统计词频
p110 关联数组 egrep -o "\b[[:alpha:]]+\b" $filename 用来只输出单词。用-o选项打印由换行符分割匹配的字符串序列。这样我们就可以在每行中只列出一个单词。
此处,awk命令用于避免对每一个单词进行迭代。因为awk默认对每一行都执行{ }块中的语句,所以就不需要手动指定循环了。
sed 流编辑器
可以完美配合正则表达式使用。一个重要功能是文本替换
替换给定文本中的字符串。 sed 's/pattern/replace_string/' filename
-i 则将替换结果应用于源文件。
之前的只替换第一处。如果要替换全部,则要在最后加一个g
eg: echo this thisthisthis | sed 's/this/THIS/g', 如果要从第三处开始,可以将g改成3g
定界符(上面的三个/)可以自己指定。当定界符与匹配样式冲突时候,要对样式的符号进行转义。
如:sed 's|te\|xt|replace\g'
1.移除空白行
sed '/^$/d' file。 /pattern/d会移除匹配样式的行。
2. 已匹配字符串标记&
在sed中,用&标记匹配样式的字符串,就能够在替换字符串时使用已匹配的内容
eg:echo this is an example | sed 's/\w\+/[&]/g'
正则表达式\w\+匹配每一个单词,然后我们用[&]替换它。而&对应于之前匹配到的单词
3. 子串匹配标记\1
&代表匹配给定样式的字符串。但是我们也可以匹配其中的一部分
echo this is digit 7 in a number | sed 's/digit \([0-9]\)/\1/'
\( \) 表示组,利于后向引用。 \1表示匹配的第一个字符串
4. 组合多个表达式
sed ‘expression’ | sed 'expression' 等价于 sed 'expresion;expression'
5. 引用
sed 可以用单引号,也可以用双引号。用双引号可以对表达式求值
cat sed_data.txt | sed 's/\b[0-9]\{3\}\b/NUMBER/g'
\b[0-9]\{3\}\b用于匹配三位数字的正则表达式。
\b是单词边界符,{3}表示匹配三次
awk
被设计用于数据流。 有很多内置功能,数组,函数等。与c语言类似,灵活性是其最大优势。
awk 'BEGIN{ print "start" } pattern { command } END { print "end" }'
工作方式:
(1). 执行BEGIN 语句块的语句
(2). 从文件或者stdin中读取一行,然后执行pattern,重复这个过程,直到文件被全部读取完毕
(3). 当读至输入流末尾,执行END语句块
1.特殊变量
NR 记录数量
NF 字段数量
$0 当前行的文本呢
$1 第一个字段的文本内容
$2 第二个字段的文本内容
2. 将外部变量值传递给awk
使用-v
3. 用getline读取行
4. 用样式对awk处理的行进行过滤
如:awk 'NR < 5'
5. 设置字段定界符
awk -F: '{ print $NF }' /etc/passwd
6. 从awk中读取命令输出
echo | awk '{ "grep root /etc/passwd" | getline cmdout ; print cmdout }'
echo 生成一个空白行
7. awk循环,及内置函数
--------应用实例-------
1. js的压缩
2. 对文件中的行,单词和字符进行迭代
迭代每一行 while read line; do echo $line; done < file.txt
迭代每一行中的每一个单词 for word in $line; do echo $word; done
完整版:while read line; do echo $line; for word in $line; do echo $word; done; done < file.txt
迭代每一个单词中的每一个字符:for((i=0;i<${#word};i++)) do echo ${word:i:1};done
完整版:while read line; do echo $line; for word in $line; do echo $word; for((i=0;i<${#word};i++)) do echo ${word:i:1};done;done; done < file.txt
${word:start_position:no_of_char} 返回变量word所包含的字符串中的一个子串
${#word}返回变量word的长度
3. paste 按列合并文件
4. 打印文件或行中的第n个单词或列
awk '{ print $5 }' filename
eg: awk -F: '{ print $5 }' /etc/passwd
5. 打印不同行或样式之间的文本
awk 'NR==M, NR==N' filename
awk '/start_pattern/, /end_pattern/' filename
这里用于awk的样式是正则表达式
6. 回文
7. 以逆序的形式打印行
8. 解析邮件地址,url
egrep -o '[A-Za-z0-9]+@[A-Za-z0-9]+\.[A-Za-z]{2,4}' url_email.txt
egrep -o "http://[a-zA-Z0-9.]+\.[a-zA-Z]{2,3}" url_email.txt
9. 打印文件中某个样式之前或之后的n行
grep -A -B
10. 在文件中移除包含某个单词的句子
通过sed用空白符替换匹配的句子
[^.]*可以匹配除句点之外的任何字符串的组合
sed 's/ [^.]*mobile phones[^.]*\.//g' sentence.txt
11. 用awk实现head, tail,tac
前10行: awk 'NR <=10' filename
后10行: awk '{ buffer[NR %10] = $0; } END{ for(i=1;i<11;i++) { print buffer[i%10] } }' filename
逆序: awk '{ buffer[NR] = $0; } END { for(i=NR; i > 0; i--) { print buffer[i] } }' filename
12. 文本切片与参数操作
替换变量内容中的部分文本
var="this is a line of text"
echo ${var/line/REPLACED}
结果为:this is a REPLACED of text
通过指定字符串的起始地址和长度来生成子串
${variable_name:start_position:length}