声明:本文首发于个人公众号:写点代码。
1 文本处理基本操作
more/less:逐屏显示文本,一般用在很长的文件查看
head/tail:查看文件头几行或者末尾几行
head -n
tail -n
wc:word count,对于文本进行计数
wc -l 按照回车符计算有多少行
wc -c 计算有多少单词
tr: translate 翻译字符,可以将一个字符串替换为另外一个字符串
tr string1 string2
sort:对文本进行排序
sort -n 表示倒序
uniq:取除重复字符串
这个重复的行表示连续的行重复。
uniq 返回去除连续重复字符串的结果
uniq -u (unique) 只保留没有重复的行
uniq -d (duplicated) 只保留重复的行
uniq -c (count) 计数同样的行出现了几次
tee:三通 将输出内容同时输出到屏幕和保存到文件。相比于重定向(>),重定向只能保存到文件。
2 正则表达式
正则表达式用来表示一个字符串的模式,其中基本正则表达式包括特殊字符六个:圆点(.),^,[,$,*,\。如果将要将这些特殊字符转换为普通字符,需要使用转义符\。圆点表示任意字符,^表示开头,$表示结尾。[]使用连接符[-]可以表示一个区间,不使用连接符[-]可以表示一个集合。*表示前0个字符重复1次或者多次。特殊需要指出的是,^只有在正则表达式首位以及$在正则表达式尾部才能作为开始和结束的标记,在其他位置都是普通字符。在[]表示集合或区间的时候,^用在开头可以表示补集,比如[^a-z],表示非小写字母。
除此之外,还有扩展的正则表达式,可以用圆括号()和表示“或”的符号|,其次,还定义了和正则表达式中的星号地位类似的+和?。*号表示它左边的单字符正则表达式的0次或多次重复,对应的,+号 表示1次或多次,?表示0次或一次。
目前主要有三种命名进行文本处理:grep,sed,awk。
grep(Global regular expression print)命令是一种文本过滤程序,按照正则表达式的规则,仅筛选出含有指定模式字符串的文本行。
grep pattern filename 在特定文件查找
grep -R pattern docment 扫描文件夹中所有
awk:文本处理语言
AWK 是一种处理文本文件的语言,是一个强大的文本分析工具。awk程序逐行扫描文本文件,并进行处理。和其它的文本处理程序一样,awk可以指定0到多个文件作为处理对象。awk有很强的功能,它是一种模式扫描和处理语言,支持条件控制,循环控制,变量定义,函数等功能。
用法1:
awk 'Program' file-list
awk程序的写法是:
condition {action}
awk把输入文件的每一行作为一个“记录”,变量NR就是行号。每行中,用空格或者
制表符分隔开的部分,叫做每个记录中的“域”。变量$1指的是第1个域内容,依次,变量$2指的是第2个域内容,……。换句话说,就是列的信息。特别的,$0指的是整个这一行的内容。BEGIN和END。BEGIN之后的动作,在awk开始处理所有文本行之前执行。同样,END之后的动作,在awk处理完所有文本行之后执行。NF是当前行的总段数,FS是当前的分隔符,默认是空格键。
program里面的内容,除了代码,其他的格式用字符串表示用空格隔开。
root@my:~# last
root pts/4 125.33.162.88 Wed Oct 28 12:54 still logged in
root pts/4 125.33.162.88 Wed Oct 28 12:51 - 12:54 (00:03)
root@my:~# last | awk '{print $1 "\t" $3}'
root 125.33.162.88
用法2:
awk -f ProgramFile file-list
programFile按照BEgin,end等格式编写,后缀保存为.awk.
//cal.awk
BEGIN{printf "--------------------------"}
{ printf $1 "\t" $3 }
END{ printf "END"}
last | awk -f cal.awk
sed(stream editor)是一个流编辑程序,当指定的处理对象为0个文件时,它从标准输
入获取输入字符流,否则,将文件中的数据作为作为输入字符流。对输入字符流进行编
辑处理,加工处理后再输送到标准输出。这两种用法的区别和awk命令类似。
用法1: sed '命令' 文件名列表
root@my:~# last |sed 's/root/fff/g'
fff pts/0 125.33.162.88 Wed Oct 28 13:04 still logged in
fff pts/4 125.33.162.88 Wed Oct 28 12:54 still logged in
sed的编辑命令有很多,这里的s命令是“替换(substitute)”第一部分是正则表达式,第二部分是替换字符串,最后的g是global flag,这一特征字符,使得s命令在一行中遇到多个模式描述的字符串时,都替换,否则,仅替换一次。
用法2: sed -f 文件名 文件名列表
sed脚本是一个sed的命令清单,启动Sed时以-f选项引导脚本文件名。Sed对于脚本中输入的命令非常挑剔,在命令的末尾不能有任何空白或文本,如果在一行中有多个命令,要用分号分隔。以#开头的行为注释行,且不能跨行。这个目前我理解,sed脚本就是一个bash脚本。
比较两个文件是否相同:
用法:cmp file1 file2
用法:diff file1 file2
这两个命令用于比较两个文件是否相同。
cmp命令逐个字节比较两个文件是否完全相同,两个文件完全相同时,不给出任何提
示。当两个文件不同时,打印出第一个不同之处。这个命令常用来判断两个文件的内容
是否完全一致,无论是ASCII码文件还是二进制格式的程序或数据文件。
root@my:~# cmp list.awk cal.awk
list.awk cal.awk differ: byte 7, line 1
diff用来比较文本文件
命令diff file1 file2每发现两个文件中的一处不同,就列出一个如何将f1.c转化为f2.c的指令,这些指令有a(Add),c(Change)和d(Delete)。指令用一个字母a,c或d表示,指令字母左边的行号是file1的行号,指令右面的行号是file2的行号。列出内容时,大于号后边的内容是需要在file1文件中增加的内容,小于号后边的内容是需要从file1中删除的内容。
root@my:~# diff list.awk cal.awk
1,9c1,3
< BEGIN
{< printf("-------------------------------------------\n")
< printf("FILENAME %s\n", FILENAME)
< printf("-------------------------------------------\n")
< }
< END{
< printf("----------------------------------------\n")
< }
< {printf("%3d:%s\n",NR,$0)}
---
> BEGIN{printf "--------------------------"}
> { printf $1 "\t" $3 }
> END{ printf "END"}
diff命令常用的选项有:
-b 逐行比较两个文件时忽略每行结尾处的多余空格。
-e 为UNIX的行编辑程序ed生成脚本文件。ed命令使用这个脚本文件编辑file1文件,
就可以变成文件file2。ed也是一个文本编辑命令。
diff -u 类似于git,版本管理系统,--表示移除,++表示添加。
说明:grep,awk,sed之间的区别是什么?
grep用来搜索字符串,awk和sed用来文本处理。awk更加灵活一些,不仅可以按照行进行梳理,也可以对一些字段进行处理,可以使用C语言。sed可以在vi中使用,可以进行编辑,也可以不保存这个编辑的结果(缓存空间),保留原始文件。
文件名通配符
文件名通配符是由shell解释,也就是shell会帮我们把我的通配符映射成所有的目标结果。