鸟哥的 Linux 私房菜第12章-正规表示法与文件格式化处理 学习笔记

来源:互联网 发布:unity3d工程师招聘 编辑:程序博客网 时间:2024/05/16 09:54

export LANG=C设定语言


grep 使用 alias 设定成为『 grep --color=auto 』的方法:

在 ~/.bashrc 内加上这行:『alias grep='grep --color=auto'』再以『 source ~/.bashrc 』来立即生效即可


[:alnum:], [:alpha:], [:upper:], [:lower:], [:digit:]:

[:alnum:] 代表英文大小写字符及数字,亦即 0-9, A-Z, a-z

[:alpha:] 代表任何英文大小写字符,亦即 A-Z, a-z

[:digit:] 代表数字而已,亦即 0-9

[:lower:] 代表小写字符,亦即 a-z

[:upper:] 代表大写字符,亦即 A-Z


练习grep:

dmesg | grep -n --color=auto 'eth'

grep -in 'the' regular_express.txt


利用中括号 [] 来搜寻集合字符:

[] 里面不论有几个字符,他都谨代表某『一个』字符

[^g]oo表示需要的是 oo ,但是 oo 前面不能是 g 就是了

[^a-z]oo

[a-zA-Z0-9]

[^[:lower:]]oo


行首与行尾字符 ^ $:

grep -n '^the' regular_express.txt  ——the 只在行首列出

grep -n '^[a-z]' regular_express.txt  ——开头是小写字符的那一行就列出

grep -n '^[[:lower:]]'

grep -n '^[^a-zA-Z]' regular_express.txt ——不想要开头是英文字母

注意:那个 ^ 符号,在字符集合符号(括号[])之内与之外是不同的! 在 [] 内代表『反向选择』,在 [] 之外则代表定位在行首的意义!

grep -n '\.$' regular_express.txt ——行尾结束为小数点 (.) 的那一行

断行字符在 Linux 与 Windows 上的差异:我们可以发现 5~9 行为 Windows 的断行字符 (^M$) ,而正常的 Linux 应该仅有第 10 行显示的那样 ($)

grep -n '^$' regular_express.txt——因为只有行首跟行尾 (^$),所以,这样就可以找出空白行啦!

====例子:

[root@www ~]# grep -v '^$' /etc/syslog.conf | grep -v '^#'

# 结果仅有 10 行,其中第一个『 -v '^$' 』代表『不要空白行』,

# 第二个『 -v '^#' 』代表『不要开头是 # 的那行』喔!

====


任意一个字符 . 与重复字符 *

*正规表示法并不是通配符

. (小数点):代表『一定有一个任意字符』的意思;
* (星星号):代表『重复前一个 0 到无穷多次』的意思,为组合形态

grep -n 'ooo*' regular_express.txt——『至少两个 o 以上的字符串』

grep -n 'g.*g' regular_express.txt ——代表 g 开头与 g 结尾,中间任意字符均可接受


限定连续 RE 字符范围 {}

grep -n 'o\{2\}' regular_express.txt——找到两个 o 的字符串

grep -n 'go\{2,5\}g' regular_express.txt——找出两个到五个 o 的连续字符串

grep -n 'go\{2,\}g' regular_express.txt——2 个 o 以上的 goooo....g

ls -l /etc | grep '^l'  ——找出 /etc/ 底下文件类型为链接文件属性的文件名


sed 工具:

范例一:将 /etc/passwd 的内容列出并且打印行号,同时,请将第 2~5 行删除!

[root@www ~]# nl /etc/passwd | sed '2,5d'

范例二:承上题,在第二行后(亦即是加在第三行)加上『drink tea?』字样!

[root@www ~]# nl /etc/passwd | sed '2a drink tea?'

如果是要在第二行前呢?『 nl /etc/passwd | sed '2i drink tea' 』就对啦!

范例三:在第二行后面加入两行字,例如『Drink tea or .....』与『drink beer?』

[root@www ~]# nl /etc/passwd | sed '2a Drink tea or ......\ > drink beer ?'

范例四:我想将第2-5行的内容取代成为『No 2-5 number』呢?

[root@www ~]# nl /etc/passwd | sed '2,5c No 2-5 number'

范例五:仅列出 /etc/passwd 档案内的第 5-7 行

[root@www ~]# nl /etc/passwd | sed -n '5,7p'

-n 代表的是『安静模式』

sed 's/要被取代的字符串/新的字符串/g'

取IP地址的例子:

ifconfig eth0 | grep 'inet addr' |  sed 's/^.*addr://g' | sed 's/Bcast.*$//g'

另外一个例子:

cat /etc/man.config | grep 'MAN'| sed 's/#.*$//g' |  sed '/^$/d'

sed直接修改档案内容(危险动作):

范例六:利用 sed 将 regular_express.txt 内每一行结尾若为 . 则换成 !

[root@www ~]# sed -i 's/\.$/\!/g' regular_express.txt

# 上头的 -i 选项可以让你的 sed 直接去修改后面接的档案内容而不是由屏幕输出喔!

范例七:利用 sed 直接在 regular_express.txt 最后一行加入『# This is a test』

[root@www ~]# sed -i '$a # This is a test' regular_express.txt

# 由于 $ 代表的是最后一行,而 a 的动作是新增,因此该档案最后新增啰!

关于-e:

cat /etc/passwd |  sed -e '4d' -e '6c no six line' > passwd.new

# 注意一下, sed 后面如果要接超过两个以上的动作时,每个动作前面得加 -e 才行!


延伸正规表示法:

grep -v '^$' regular_express.txt | grep -v '^#'   可以改写成

egrep -v '^$|^#' regular_express.txt


格式化打印: printf

选项与参数: 关于格式方面的几个特殊样式: \a 警告声音输出 \b 退格键(backspace) \f 清除屏幕 (form feed) \n 输出新的一行 \r 亦即 Enter 按键 \t 水平的 [tab] 按键 \v 垂直的 [tab] 按键 \xNN NN 为两位数的数字,可以转换数字成为字符。关于 C 程序语言内,常见的变数格式 %ns 那个 n 是数字, s 代表 string ,亦即多少个字符; %ni 那个 n 是数字, i 代表 integer ,亦即多少整数字数; %N.nf 那个 n 与 N 都是数字, f 代表 floating (浮点),如果有小数字数, 假设我共要十个位数,但小数点有两位,即为 %10.2f 啰!

例子:printf '%s\t %s\t %s\t %s\t %s\t \n' $(cat printf.txt)

例子:printf '%10s %5i %5i %5i %8.2f \n' $(cat printf.txt | grep -v Name)

例子:printf '\x45\n'  #列出 16 进位数值 45 代表的字符为何?


awk:好用的数据处理工具:

awk 通常运作的模式是这样的:awk '条件类型1{动作1} 条件类型2{动作2} ...' filename

例子:我们用 last 可以将登入者的数据取出来,仅取出前五行,要取出账号与登入者的 IP ,且账号与 IP 之间以 [tab] 隔开:

[root@www ~]# last -n 5 | awk '{print $1 "\t" $3}'

awk 是『以行为一次处理的单位』, 而『以字段为最小的处理单位』。

awk 的内建变量:

NF 每一行 ($0) 拥有的字段总数

NR 目前 awk 所处理的是『第几行』数据

FS 目前的分隔字符,默认是空格键

利用 BEGIN 这个关键词预先设定 awk 的变量:

[root@www ~]# cat /etc/passwd |  awk 'BEGIN {FS=":"} $3 < 10 {print $1 "\t " $3}'

除了 BEGIN 之外,我们还有 END。

一个薪资表的例子(第一行只是说明,所以第一行不要进行加总 (NR==1 时处理);第二行以后就会有加总的情况出现 (NR>=2 以后处理)):

cat pay.txt |  awk 'NR==1{printf "%10s %10s %10s %10s %10s\n",$1,$2,$3,$4,"Total" } NR>=2{total = $2 + $3 + $4 ; printf "%10s %10d %10d %10d %10.2f\n", $1, $2, $3, $4, total}' 

输入结果:

Name 1st 2nd 3th Total

VBird 23000 24000 25000 72000.00

DMTsai 21000 20000 23000 64000.00

Bird2 43000 42000 41000 126000.00

awk 的动作内 {} 也是支持 if (条件),上面的指令可以修订成为这样:

cat pay.txt |  awk '{if(NR==1) printf "%10s %10s %10s %10s %10s\n",$1,$2,$3,$4,"Total"} NR>=2{total = $2 + $3 + $4 ; printf "%10s %10d %10d %10d %10.2f\n", $1, $2, $3, $4, total}'

注意:awk 的指令间隔:所有 awk 的动作,亦即在 {} 内的动作,如果有需要多个指令辅助时,可利用分号『;』间隔, 或者直接以 [Enter] 按键来隔开每个指令。


档案比对工具

diff,以行为单为来比对的:

用法:diff [-bBi] from-file to-file

cmp,主要利用『字节』单位去比对:

用法:cmp [-s] file1 file2

patch,与diff配合使用,此处略


档案打印准备: pr

pr /etc/man.config