Linux下的shell编程(三)BY 四喜三顺
正则表达式:
-------------------------------------------------------------------------------------------
^
行起始
^tux
匹配以tux起始的行
$ 行结尾
tux$
匹配以tux结尾的行
.
匹配任意字符
Hack.
匹配Hack1、Hacki,但不匹配Hack12或Hackij,只匹配单个字符
[]
匹配[]内1个字符
coo[kl]
匹配cook或者cool
[^]
匹配[]以外1个字符 9[^01]
匹配92、93等,不匹配91和90
[-]
匹配[-]内1个字符 [1-5]
匹配1、2、3、4、5
?
匹配之前项1次或0次 colou?r
匹配colour或者color
+
匹配之前项1次或多次 roll-9+
匹配roll-9、roll-99、roll-999等
*
匹配之前项0次或多次
co*l
匹配cl、col、cool、coool等
()
创建1个用于匹配的字串 max(tri)?
匹配maxtri或者max
{n}
匹配之前项n次
[0-9]{3} 匹配任意1个3位数
{n,}
至少匹配n次
[0-9]{2,} 匹配任意1个2位数或更多位数
{n,m}
匹配最小n次,最大m次 [0-9]{2,5}
匹配从2位数到5位数之间任意1个数字
|
匹配|两边任一项 O(1st|2nd)
匹配O1st或者O2nd
\ 转义符
a\.b
匹配a.b,但不匹配aib、akb等,忽略了.的意义
-------------------------------------------------------------------------------------------
[:alnum:]
字母与数字
[:alpha:] 字母(含大写小写)
[:lower:]
小写字母
[:upper:] 大写字母
[:digit:]
数字
[:blank:] 空格与制表符
[:punct:]
标点符号
[:space:]
包括换行符、回车等在内的所有空白字符
-------------------------------------------------------------------------------------------
\b
单词边界 \bcool\b匹配cool
\B
非单词边界 cool\B不匹配cool,可以匹配coolant
\d
[0-9]
\D [^0-9]
\w
[0-9a-zA-Z_]
\W [^0-9a-zA-Z_]
\n
匹配1个新行
\r 匹配回车
\s
匹配单个空白字符
\S
匹配单个非空白字符
-------------------------------------------------------------------------------------------
例如:电子邮件地址的正则表达式
[A-Za-z0-9.]+@[A-Za-z0-9.]+\.[a-zA-Z]{2,4}
grep的用法:
(1)查找
$ grep
"matchtext" file1 file2 ...
#在file1、file2等文件中查找matchtext
$ grep -E "[a-z]" file1
file2... #正则表达式,在file1、file2等文件中查找小写字母
$
egrep "[a-z]" file1 file2...
#正则表达式,在file1、file2等文件中查找小写字母
(2)在多级目录中对文本进行搜索
$ grep "text" . -R
-n #对当前目录查找
例: $ cd
src_dir
$ grep "test_function()" . -R -n
./miscutils/test.c:16:test_function()
意为test_function()在miscutils/test.c的第16行
(3)同时匹配多个样式
$
grep -e "pattern1" -e "pattern2"
$ grep -f pattern_file
source_file
#先在pattern_file中逐行写下需要匹配的样式
(4)搜索中包括或者排除文件递归搜索
$ grep "main()" . -r
--include *.{c,cpp} #在当前目录中只递归搜索所有的c和cpp文件
$ grep "main()"
. -r --exclude "README"
#在搜索中排除所有的README文件
$ grep "main()" . -r --exclude-dir
#在搜索中排除目录
(5)静默输出
看下面的脚本:
--------------------------------------------------------
#!
/bin/bash
# grep.sh
if [ $# -ne 2 ];
then
echo "$0 match_text
filenameaaaa"
fi
match_text=$1
filename=$2
grep -q
$match_text $filename #成功返回0,不成功返回非0值
if [ $? -eq 0
];
then
echo "The text exists in the file"
else
echo "The text does
not exist in the
file"
fi
---------------------------------------------------------
运行时:$
./grep.sh "Obama" USA_news.txt
sed用法:
(1)替换给定文本,从stdin中读取
$ sed
‘s/pattern/replace_string/‘ file
$ cat file | sed ‘s/pattern/replace_string/‘
file
(2)替换给定文本,写入到原文件
$ sed -i ‘s/pattern/replace_string/‘
file
(3)替换给定文本,写入到新文件
$ sed ‘s/pattern/replace_string/‘ file >
newfile
以上(1)(2)(3)只会将每一行的第一个pattern替换掉,如果想替换全部,需加上参数g
$ sed
‘s/pattern/replace_string/g‘ file
如果要从第N个pattern开始替换,则:
$ sed
‘s/pattern/replace_string/Ng‘ file
‘s/pattern/replace_string/‘
也可以写成‘s:pattern:replace_string:‘或‘s|pattern|replace_string|‘
需要主义的是,如果pattern本身内部有|或者:等的时候,需要转义符,如:sed
‘s|te\|xt|replace|g‘
移除空白行: $ sed ‘/^$/d‘
file #空白行的正则表达式是^$
移除匹配样式的行:
$ sed ‘/pattern/d‘ file
用&标记匹配样式字符串:$ cat file | sed
‘s/\w\+/[&]/g‘ file
#这里正则表达式\w\+匹配每一个单词,用[&]替换它,&代表匹配的单词
例题:输入dkdkkiaoiqqiwideiujdiwd,统计每个字母出现字数并按字母表排序
INPUT="dkdkkiaoiqqiwideiujdiwd"
OUTPUT=`echo
$INPUT | sed ‘s/[^n]/&\n/g‘ | sed ‘/^$/d‘ | sort | uniq -c | tr -d ‘ \n‘
`
echo $OUTPUT
结果为:1a5d1e6i1j3k1o2q1u2w
其中:
sed ‘s/[^n]/&\n/g‘
#在每个字符后追加1个换行符,使得每行只出现一个字符
sed ‘/^$/d‘
#最后1个字符会被sed替换成“字符+\n”,所以多出1个换行符并在最后形成1个空行,这个命令删除最后的空行
sort
#排序
uniq
-c
#打印出每行各重复了多少次
tr -d ‘ \n‘
#删除空格和换行符,形成最终结果
awk用法:
awk ‘BEGIN{print
"start"} pattern{commands} END{print "end"}‘
filename
即由3部分组成,BEGIN、END、能够使用模式匹配的通用语句块,3部分可选
机制为:第一步执行BEGIN中的语句;第二步从文件中读取1行,执行pattern{commands},重复这个过程直至文件全部读取完毕;第三步执行END中的语句。
如:$
awk ‘BEGIN {i=0} {i++} END {print i}‘ filename
#统计filename文件的行数
更常见的形式是 awk ‘pattern{commands}‘ filename
#pattern 表示 AWK 在数据中查找的内容,而 commands
是在找到匹配内容时所执行的一系列命令。
awk的特殊变量:
NR
记录行号
NF 记录字段数
$0
当前行的文字内容
$1 第一个字段的文本内容
$2
第二个字段的文本内容
示例:
$ echo "line1 f2 f3"|awk ‘{print "Line
number:"NR}‘
Line number:1
$ echo "line1 f2 f3"|awk ‘{print "Number of
fields:"NF}‘
Number of fields:3
$ echo "line1 f2 f3"|awk ‘{print
"$2="$2}‘
$2=f2
$ echo "line1 f2 f3"|awk ‘{print
"$3="$3}‘
$3=f3
打印文件每一行的第三和第二个单词: $ awk ‘{print $3
$2}‘ filename
统计文件行数: $ awk ‘END{print NR}‘
filename
wget用法:
例如网站下载
$ wget
http://att.newsmth.net/att.php?p.1349.56166.262.jpg
$ xdg-open
att.php\?p.1349.56166.262.jpg
爬虫技术:
$ wget -r -N -l DEPTH
URL
其中:-r代表递归下载,-N代表允许对文件使用时间戳,-l
DEPTH指定页面层级
lynx用法:
lynx是纯文本的浏览器,但利用lynx指令可以将它的纯文本格式输出作为网页来获取
下面的命令将网页以ASCII字符的形式下载到文本文件中
$
lynx -dump URL > plain_text_page.txt
curl用法:
$ curl URL
#下载
$ curl URL
--silent #下载,不显示进度信息
$ curl URL --silent
-o #下载,不显示进度信息,将下载数据写入文件,而不是写入标准输出
$
curl URL --silent -o new_filename
#下载,不显示进度信息,将下载数据写入新的文件
$ curl URL --silent -o new_filename
--progress
#下载,不显示进度信息,将下载数据写入新的文件,下载过程显示进度条
$ curl URL --max-filesize
bytes #指定最大下载量
$ curl -u user:pass URL
#指定用户名密码
$ curl -u user URL
#指定用户名,需要密码提示
综合练习:制作图片抓取器及下载工具
---------------------------------------------------------------------------------------------
00
#! /bin/bash
01 #
downloader.sh
02
03 if [ $# -ne 3 ];
04
then
05 echo "Usage: $0 URL -d
DIRECTORY"
06 exit -1
07
fi
08
09 for i in {1..4}
10
do
11 case $1 in
12
-d) shift; directory=$1; shift ;;
13
*) url=${url:-$1}; shift;;
14
esac
15 done
16
17 mkdir -p
$directory;
18 baseurl=$(echo $url | egrep -o
"https?://[a-z.]+")
19
20 curl -s $url | egrep -o
"<img src=[^>]*>"|sed ‘s/<img src=\"\([^"]*\).*/\1/g‘ >
/tmp/$$.list
21
22 sed -i "s|^/|$baseurl/|"
/tmp/$$.list
23
24 cd
$directory;
25
26 while read filename;
27
do
28 curl -s -O "$filename"
--silent
29
30 done <
/tmp/$$.list
------------------------------------------------------------------------------------------------
解析:
(1)$#
代表添加到Shell的参数个数;$0
代表Shell本身的文件名;$1是第1参数、$2是第2参数……
(2)第3-7行意为,判断命令行参数是不是3个,如果不是,退出,并打印出用法提示
(3)shift命令用于左移。比如shift
3表示原来的$4现在变成$1,原来的$5现在变成$2等等,原来的$1、$2、$3丢弃,$0不移动。不带参数的shift命令相当于shift
1。
(4)第12行意为,对第一个参数$1求值,以匹配-d等被检查到的字符串参数,我们可以写成 $ ./downloader.sh -d DIR URL
或者 $ ./downloader.sh URL -d
DIR等。使用shift后,$2值赋给$1,再使用shift,$3值赋给$1,以此类推,因此我们通过$1就可以对所有的参数进行求值。
(5)第13行意为,*)对于默认值,在这里能够匹配除了-d以外的任意内容。如果实际情况是$1="
"或$1=URL,我们需要采用$1=URL,所以我们使用url=${url:-$1},如果url不为空,返回URL值,否则,返回$1的值
(6)第20行,egrep
-o "<img
src=[^>]*>"只打印包括属性值在内的<img>标记,[^>]*用来匹配除了>以外的所有字符
(7)第20行,sed
‘s/<img
src=\"\([^"]*\).*/\1/g‘对src="url"进行解析,从已经解析出来的<img>中得到所有的图像文件URL
(8)第22行,由于图像文件有绝对路径(如http://example.com/image.jpg)和相对路径(/image.jpg),对于后者,以/开头,需要用基址URL(base
URL)把它转换成http://example.com/image.jpg,用第22行把所有的/替换成baseurl
(9)第26行,while对图片的URL列表进行逐行迭代,并用curl下载图像文件
其他管理类命令:
$
du filename #列出filename文件占用的磁盘空间,du代表disk
usage
$ df
#列出磁盘空余情况,df代表disk free
$ time command
#执行指令,并列出指令运行时间
$ who
#获取当前登录用户的相关信息
$ w
#获取当前登录用户的相关信息
$ ps
#收集系统中进程的详细信息,包括PID等
$ which
command #找出某个命令的位置
$ whereis
command #找出某个命令的位置,并打印出其对应的命令手册的位置以及命令源代码的路径(如果有)
$ file
filename #确定文件类型
$ whatis
command #输出作为参数的命令的简短描述信息
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。