您的位置:首页 > 运维架构 > Linux

《Unix & Linux 大学教程》 - 第十六、十七章 学习笔记

2012-08-21 10:56 477 查看
学习笔记,内容基础,适合初学者。

阅读之前,请务必花30秒查看前言说明(在第一、二章前面部分)


《Unix & Linux 大学教程》 - 第一、二章 学习笔记 Unix简介 & 什么是Linux?什么是Unix

《Unix & Linux 大学教程》 - 第三、四章 学习笔记 Unix连接 & 开始使用Unix

《Unix & Linux 大学教程》 - 第五、六章 学习笔记 GUI:图形用户界面 & Unix工作环境

《Unix & Linux 大学教程》 - 第七、八章 学习笔记 Unix键盘使用 & 能够立即使用的程序

《Unix & Linux 大学教程》 - 第九、十章 学习笔记 文档资料:Unix手册与Info & 命令语法

《Unix & Linux 大学教程》 - 第十一、十二章 学习笔记 shell & 使用shell:变量和选项

《Unix & Linux 大学教程》 - 第十三章 学习笔记 使用shell:命令和定制

《Unix & Linux 大学教程》 - 第十四、十五章 学习笔记 使用shell:初始化文件

《Unix & Linux 大学教程》 - 第十六、十七章 学习笔记 过滤器:简介和基本操作

《Unix & Linux 大学教程》 - 第十八章 学习笔记 过滤器:统计和格式化

《Unix & Linux 大学教程》 - 第十九章(一) 学习笔记 过滤器:选取、排序、组合及变换

《Unix & Linux 大学教程》 - 第十九章(二)、第二十章 学习笔记 过滤器:选取、排序、组合及变换 正则表达式

《Unix & Linux 大学教程》 - 第二十一章 学习笔记 显示文件

《Unix & Linux 大学教程》 - 第二十二章(一) 学习笔记 vi文本编辑器(一)

《Unix & Linux 大学教程》 - 第二十二章(二) 学习笔记 vi文本编辑器(二)

《Unix & Linux 大学教程》 - 第二十二章(三) 学习笔记 vi文本编辑器(三)

《Unix & Linux 大学教程》 - 第二十三章 学习笔记 Unix文件系统

《Unix & Linux 大学教程》 - 第二十四章 学习笔记 目录操作

《Unix & Linux 大学教程》 - 第二十五章 学习笔记 文件操作

《Unix & Linux 大学教程》 - 第二十六章(一) 学习笔记 进程和作业控制

[b]《Unix & Linux 大学教程》 - 第二十六章(二) 学习笔记 进程和作业控制
[/b]


第十六章:过滤器:简介和基本操作

基础知识:

cat(catenate,to join in a chain)

每次一行从标准输入读取数据,完成处理后将结果每次一行的写到标准输出。

执行cat后,控制台等待输入,按下return时,之前键入的一行发送到cat,然后cat再输出,所以在屏幕上面可以看到两行相同内容的输出。

作用

在管道中不需要使用

在I/O重定向中应用较多

cat > data

将标准输出重定向到data,可以快速建立文件。当然也可以追加到文件(>>)。

cat < data

将data作为cat的标准输入,输出到屏幕上。这里重定向符号可以省略(cat data)。cat没有翻页功能,当文件内容较多的时候,只显示文件最后的内容。

cat < data > newdata

可以利用cat 复制文件。

cat [file...]

可以利用cat从多个文件读取收集数据(大多数过滤器都允许指定多个文件名作为参数)。

不要将输出重定向到一个文件上

cat name address > name

上面的命令无法完成任务!原因在于shell处理重定向的方式。在冲虚将标准输出重定向到文件之前,shell必须确保这个文件存在并且是空的,如果不存在,shell将其创建;如果存在,shell将其清空。

首先name被清空,然后address输出到name中, 和cat address > name的结果是一样的,shell会给出提示:

cat: name: input file is output file

但是这时name已经被清空了!

可以改用cat address >> name

cat [-bns] [file...]

-n(number):在每行前面加一个行号

-b(blank):和-n一起使用,告诉cat不要对空白行编号

-s(squeeze):将多个连续空白行替换为一个空白行

书中一个cat应用总结,都是上面将过的内容,而且有些还是重复的。

语法作用
cat > file从键盘读取数据,创建新文件或者替换已有文件
cat >> file从键盘读取数据,将数据追加到已有文件中
cat < file显示一个已有文件
cat file显示一个已有文件
cat <file1 > file2复制文件
cat file1 file2 file3 | less组合多个文件,每次一屏的显示结果。
cat file1 file2 file3 > file4组合多个文件,将输出保存到一个不同文件中
cat file1 file2 file3 | program组合多个文件,将输出管道出送给另一个程序
split

语法

split [-d] [-a num] [-l lines] [file [prefix]]

num是创建文件名时用作文件名后缀的字符或者数字数量

lines是每个新文件所包含行的最大数量

file是输入文件的名称

prefix是创建文件时使用的名称

split默认创建1000行数据的文件

split data(将data分割为若干个每个含1000行数据的文件)

split -l 5000 data(将data分割为若干个每个含5000行数据的文件)

split默认以字母x开头,类似于

xaa xab xac xad xae xaf xag xah xai

如果之前有同名文件,则被覆盖。

split -d -l 5000 data

改用数字做后缀

x00 x01 x02 x03 ......

split -d -l 5000 data y

修改文件名前缀

y00 y01 y02 y03 ......

split -a 3 data

split -d -a 3 data

设置文件名后缀长度

xaaa xaab xaac xaad ......

x001 x002 x003 x004 ......

tac

语法

tac [file...]

tac将文本写入标准输出之前,将文本行的顺序反转(第一行成为最后一行,第二行成为倒数第二行……)。

tac log > reverse-log

将log文件行反转之后输出到reverse-log中。

rev

语法

rev [file...]

反转字符顺序

rev data | tac

即反转了行,也反转了每行的字符。

head、tail

语法

head [-n lines] [file...]

tail [-n lines] [file...]

head从数据的开头许选择数据行

tail从数据的结尾选择数据行

head、tail默认选取10行数据

cat data1 data2 | sort | tail -n 300 | less

cat data1 data2 | sort | head > newdata

其中n可以省略,变为

tail -15 file

查看不断增长的文件

语法

tail -f [-n [+]lines] [file...]

(需要按下^C后tail才会停止,否则一直等到file的新输出)

colrm(column remove)

语法

colrm [startcol [endcol]]

程序从标准输入读取数据,删除指定的数据列,然后将剩余数据写入标准输出。

其中startcol和endcol指定要移除奇遇的开头和末尾。列的编号从1开始。

比如,我的一个文件名为text的文本文件中有如下两行数据:

1234567

abcdefg

那么我想删除第3-5列

cat text | colrm 3 5

结果为(当然,上面的命令没有改变text文件本身)

1267

abfg

注意:列的编号从1开始,并且是闭区间,而非半开半闭。

第十七章:过滤器:比较和抽取

基础知识:

重要的文件比较程序和排序文件以及从文件中选取数据的相关程序

过滤器作用章号文件类型文件数量
cmp比较两个文件17二进制或者文本2个
comm比较两个有序文件,显示区别17文本:有序2个
diff比较两个文件,显示区别17文本2个
sdiff比较两个文件,显示区别17文本2个
cut从数据中抽取指定列(字段)17文本1个或多个
paste组合数据列17文本1个或多个
sort排序数据19文本1个或多个
uniq选取重复/唯一行19文本1个
grep选取包含指定模式的行19文本个或多个
look选取以指定模式开头的行19文本:有序1个
cmp

语法

cmp file1 file2

逐字节的比较,如果相同,则无任何输出,否则会看到如下类似提示:

file1 file2 differ: byte 4, line 1

无须关心文件类型

comm

语法

comm [-123] file1 file2

按行比较两个有序文件,并显示区别。

该程序以3列显示输出:

第一列:包含只在第一个文件中有的行

第二列:包含只在第二个文件中有的行

第三列:包含两个文件都有的行

diff

语法

diff [-bBiqswy] [-c|-Clines|-u|-Ulines] file1 file2

lines是说明上下文关系的行号

diff输出使用3个不同的单字符指示:

c(change):改变

d(delete):删除

a(append):追加

每个字符左右都会有一串行号,左边的数字指第一个文件中的行,右边的数字指第二个文件中的行。

第一个文件中的行由“<”(小于号)字符标记;第二个文件中的行由一个“>”(大于号)字符标记。两组行被由若干个连字符构成的直线分隔。

我们来比较一下android4.0和android4.1的package/app下有神马变化

ls -1 /media/dfaf020c-d352-4c0d-ba00-71a419011550/android4.0/packages/apps > android40

ls -1 /media/dfaf020c-d352-4c0d-ba00-71a419011550/android4.1/packages/apps > android41

将packages/apps下的文件列表写到文件中,每行一个文件

然后比较一下这两个文件

diff android41 android40

log如下:

18d17
< LegacyCamera

18d17是说如果第一个文件这样做,那么就能和第二个文件相同。
那么18d17是神马意思,d表示删除,在第一个文件中删除第18行,那么就和第二个文件相同了(17可以省略,表示在第二个文件中第17行后发现了区别)

下面再用同样的方法看看4.0和4.1中Camera下的文件列表区别:

ls -1 /media/dfaf020c-d352-4c0d-ba00-71a419011550/android4.1/packages/apps/Camera > android41

cat android41 写道
jni

MODULE_LICENSE_APACHE2

NOTICE

perftests

res

src

tests
ls -1 /media/dfaf020c-d352-4c0d-ba00-71a419011550/android4.0/packages/apps/Camera > android40

cat android40 写道
AndroidManifest.xml

Android.mk

CleanSpec.mk

jni

MODULE_LICENSE_APACHE2

NOTICE

proguard.flags

res

src

tests
diff android41 android40

log 写道
0a1,3

> AndroidManifest.xml

> Android.mk

> CleanSpec.mk

4c7

< perftests

---

> proguard.flags
将第一个文件(android41)的第0行插入第二个文件(android40)的1-3行

将第一个文件(android41)的第4行(perftests)改为第二个文件(android40)的第七行(proguard.flags)

-i:忽略大小写的区别

-w:忽略所有空白字符(xx和x x认为是一样的)

-b:忽略空白字符数量上的区别(x x和x x认为是一样的,但xx和x x认为是不一样的)

-B(blank lines,空白行):忽略所有空白行

-q(quiet,静止):当两个文件不同时,省略所有细节(和cmp相同,但是只能比较文本)。

-s(same,相同):当两个文件相同时,显示结果。内容大概如下

Files file1 and file2 are identical

-c(context,上下文):不再简洁,易理解

diff -c android41 android40 写道
*** android41 2012-08-20 15:18:05.735840338 +0800

--- android40 2012-08-20 15:18:15.265840419 +0800

***************

*** 1,7 ****

jni

MODULE_LICENSE_APACHE2

NOTICE

! perftests

res

src

tests

--- 1,10 ----

+ AndroidManifest.xml

+ Android.mk

+ CleanSpec.mk

jni

MODULE_LICENSE_APACHE2

NOTICE

! proguard.flags

res

src

tests
输出的前两行是两个文件的信息

然后是每个文件的摘录

第一个文件的1-7行,第4行需要修改

第二个文件的1-10行,第一个文件需要插入第二个文件的1-3行,第四行需要修改为第七行

(diff -C5 file1 file2,改变显示上下文的行数)

-u(unified output,统一输出):类似-c,但是没有重复行

diff -u android41 android40 写道
--- android41 2012-08-20 15:18:05.735840338 +0800

+++ android40 2012-08-20 15:18:15.265840419 +0800

@@ -1,7 +1,10 @@

+AndroidManifest.xml

+Android.mk

+CleanSpec.mk

jni

MODULE_LICENSE_APACHE2

NOTICE

-perftests

+proguard.flags

res

src

tests
(diff -U5 file1 file2,改变显示上下文的行数)

-y:两个文件行并排显示(可以使用sdiff)

diff -y file1 file2 同 sdiff file1 file2

sdiff

语法

sdiff [-bBilsW] [-w columns] file1 file2

-l:当两个文件拥有共同行时,只显示左边的列

-s(same,相同):不显示在两个文件中相同的任何行

-i:忽略大小写的区别

-w:改变列的宽度

-W:忽略所有空白字符(diff使用-w)

-b:忽略空白字符数量上的区别(x x和x x认为是一样的,但xx和x x认为是不一样的)

-B(blank lines,空白行):忽略所有空白行

cut

语法

cut -c list [file...]:抽取数据列

list是要抽取列的列表

file是输入文件的名称

ls -l 写道
total 128

-rw-r--r-- 1 su1216 su1216 107 2012-08-20 15:18 android40

-rw-r--r-- 1 su1216 su1216 58 2012-08-20 15:18 android41

-rw-r--r-- 1 su1216 su1216 108294 2012-08-06 09:54 hs_err_pid2095.log

-rw-r--r-- 1 su1216 su1216 16 2012-08-20 13:25 text

-rw-r--r-- 1 su1216 su1216 19 2012-08-20 14:10 x0000

-rw-r--r-- 1 su1216 su1216 17 2012-08-20 14:08 x0001
下面提取权限和日期部分

ls -l | cut -c 1-10,35-50

log 写道
total 128

-rw-r--r--2012-08-20 15:18

-rw-r--r--2012-08-20 15:18

-rw-r--r--2012-08-06 09:54

-rw-r--r--2012-08-20 13:25

-rw-r--r--2012-08-20 14:10

-rw-r--r--2012-08-20 14:08
ls -l | cut -c1-10,35-50(-c和后面数字之间的空格可以省略)

cut -f list [-d delimiter] [-s] [file...]:从文件行中抽取字段

list是要抽取字段的列表

delimiter是分隔字段所使用的定界符(delimiter)

file是输入文件的名称

-s(suppress,抑制):遇到不包含任何定界符的行,使用此选项可以抛弃这样的行。

以/etc/passwd这个文件为例,下面截取一部分这个文件的内容:

cat /etc/passwd 写道
root:x:0:0:root:/root:/bin/bash

daemon:x:1:1:daemon:/usr/sbin:/bin/sh

bin:x:2:2:bin:/bin:/bin/sh

sys:x:3:3:sys:/dev:/bin/sh

sync:x:4:65534:sync:/bin:/bin/sync

games:x:5:60:games:/usr/games:/bin/sh

man:x:6:12:man:/var/cache/man:/bin/sh

lp:x:7:7:lp:/var/spool/lpd:/bin/sh

mail:x:8:8:mail:/var/mail:/bin/sh

news:x:9:9:news:/var/spool/news:/bin/sh
cut -f 1 3-5 -d ':' /etc/passwd

我们提取每行的1,3,4,5个字段,其中冒号作为定界符。

写道
root:0:0:root

daemon:1:1:daemon

bin:2:2:bin

sys:3:3:sys

sync:4:65534:sync

games:5:60:games

man:6:12:man

lp:7:7:lp

mail:8:8:mail

news:9:9:news
paste

语法

paste [-d char...] [file...]

char作为分隔符

file是输入文件的名称

paste可以将几个文件(每个文件都包含一列数据)组成一个大表。也可以将连续的数据行组合起来,构建多个列。

paste和cat有点相似,paste水平组合数据,cat竖直组合数据。

下面我们先把/etc/passwd拆分掉,我们就取前四列

cut -f 1 -d ':' /etc/passwd > /home/su1216/linux_test/c1

cut -f 2 -d ':' /etc/passwd > /home/su1216/linux_test/c2

cut -f 3 -d ':' /etc/passwd > /home/su1216/linux_test/c3

cut -f 4 -d ':' /etc/passwd > /home/su1216/linux_test/c4

然后我们再把它们拼到一起

paste /home/su1216/linux_test/c1 /home/su1216/linux_test/c2 /home/su1216/linux_test/c3 /home/su1216/linux_test/c4 > /home/su1216/linux_test/c



上面截取了部分结果,同之前的passwd文件基本一致,因为没有加分隔符

每列的之间放置了一个制表符(默认),Unix假设制表符为每8个位置一个,且以位置1为起点。

指定冒号为分隔符

paste -d ':' /home/su1216/linux_test/c1 /home/su1216/linux_test/c2 /home/su1216/linux_test/c3 /home/su1216/linux_test/c4 > /home/su1216/linux_test/c

也可以指定多个分隔符,当有多个分隔符时,paste交替使用分隔符。

paste -d '|&' /home/su1216/linux_test/c1 /home/su1216/linux_test/c2 /home/su1216/linux_test/c3 /home/su1216/linux_test/c4 > /home/su1216/linux_test/c

结果如下



名词解释:

version control system:版本控制系统

source code control system(SCCS):代码控制系统

revision control system(RCS):修订控制系统

comma-separated value(CSV):逗号分隔值

一些有用的过滤器

过滤器章号参阅作用
awk--perl编程语言:操作文本
cat16split、tac、rev组合文件:复制标准输入到标准输出
colrm16cut、join、paste删除指定的数据列
comm17cmp、diff、sdiff比较两个有序文件,显示区别
cmp17comm、diff、sdiff比较两个文件
cut17colrm、join、paste从数据中抽取指定列(字段)
diff17cmp、comm、sdiff比较两个文件,显示不同
expand18unexpand将制表符转为空格
fold18fmt、pr将长行格式化成较短的行
fmt18fold、pr格式化段落,从而使它们看上去更漂亮
grep19look、strings选择包含指定模式的行
head16tail从数据的开头选择行
join19colrm、cut、paste

基于公用字段,组合数据列
look19grep选择以指定模式开头的行
nl18wc创建行号
paste17colrm、cut、join组合数据列
perl--awk编程语言:操作文本,文件,进程
pr18fold,fmt将文本格式化为页或者列
rev16cat、tac每行数据中的字符反序排列
sdiff17cmp、comm、diff比较两个文件,显示区别
sed19tr非交互式文本编辑
sort19tsort、uniq排序数据:检查数据是否有序
split16cat将大文件分隔成较小的文件
strings19grep在二进制文件中搜索字符串
tac16cat、rev组合文件,同时将文本行的顺序反转
tail16head从数据的末尾选择行
tr19sed改变或者删除选定的字符
tsort19sort根据偏序创建全序
unexpand18expand将空格转变成制表符
uniq19sort选择重复/唯一行
wc18nl统计行数、单词数和字符数

转贴请保留以下链接

本人blog地址

http://su1216.iteye.com/

http://blog.csdn.net/su1216/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: