原文地址:http://vbird.dic.ksu.edu.tw/linux_basic/0330regularex_4.php
文件的格式化与相关处理
接下来让我们来将文件进行一些简单的编排吧!底下这些动作可以将你的信息进行排版的动作, 不需要重新以 vim 去编辑,透过数据流重导向配合底下介绍的 printf 功能,以及 awk 命令, 就可以让你的信息以你想要的模样来输出了!试看看吧!
格式化列印: printf
在很多时候,我们可能需要将自己的数据给他格式化输出的! 举例来说,考试卷分数的输出,姓名与科目及分数之间,总是可以稍微作个比较漂亮的版面配置吧? 例如我想要输出底下的样式:
Name Chinese English Math Average |
上表的数据主要分成五个栏位,各个栏位之间可使用 tab 或空白键进行分隔。 请将上表的数据转存成为 printf.txt 档名,等一下我们会利用这个文件来进行几个小练习的。 因为每个栏位的原始数据长度其实并非是如此固定的 (Chinese 长度就是比 Name 要多), 而我就是想要如此表示出这些数据,此时,就得需要列印格式管理员 printf 的帮忙了! printf 可以帮我们将数据输出的结果格式化,而且而支持一些特殊的字符~底下我们就来看看!
[root@www ~]# printf '列印格式' 实际内容 |
接下来我们来进行几个常见的练习。假设所有的数据都是一般文字 (这也是最常见的状态),因此最常用来分隔数据的符号就是 [Tab] 啦!因为 [Tab] 按键可以将数据作个整齐的排列!那么如何利用 printf 呢?参考底下这个范例:
范例一:将刚刚上头数据的文件 (printf.txt) 内容仅列出姓名与成绩:(用 [tab] 分隔) |
由於 printf 并不是管线命令,因此我们得要透过类似上面的功能,将文件内容先提出来给 printf 作为后续的数据才行。 如上所示,我们将每个数据都以 [tab] 作为分隔,但是由於 Chinese 长度太长,导致 English 中间多了一个 [tab] 来将数据排列整齐!啊~结果就看到数据对齐结果的差异了!
另外,在 printf 后续的那一段格式中,%s 代表一个不固定长度的字串,而字串与字串中间就以 \t 这个 [tab] 分隔符号来处理!你要记得的是,由於 \t 与 %s 中间还有空格,因此每个字串间会有一个 [tab] 与一个空白键的分隔喔!
既然每个栏位的长度不固定会造成上述的困扰,那我将每个栏位固定就好啦!没错没错!这样想非常好! 所以我们就将数据给他进行固定栏位长度的设计吧!
范例二:将上述数据关於第二行以后,分别以字串、整数、小数点来显示: |
上面这一串格式想必您看得很辛苦!没关系!一个一个来解释!上面的格式共分为五个栏位, %10s 代表的是一个长度为 10 个字节的字串栏位,%5i 代表的是长度为 5 个字节的数字栏位,至於那个 %8.2f 则代表长度为 8 个字节的具有小数点的栏位,其中小数点有两个字节宽度。我们可以使用底下的说明来介绍 %8.2f 的意义:
字节宽度: 12345678
%8.2f意义:00000.00
如上所述,全部的宽度仅有 8 个字节,整数部分占有 5 个字节,小数点本身 (.) 占一位,小数点下的位数则有两位。 这种格式经常使用於数值程序的设计中!这样了解乎?自己试看看如果要将小数点位数变成 1 位又该如何处理?
printf 除了可以格式化处理之外,他还可以依据 ASCII 的数字与图形对应来显示数据喔(注3)! 举例来说 16 进位的 45 可以得到什么 ASCII 的显示图 (其实是字节啦)?
范例三:列出 16 进位数值 45 代表的字节为何? |
printf 的使用相当的广泛喔!包括等一下后面会提到的 awk 以及在 C 程序语言当中使用的萤幕输出, 都是利用 printf 呢!鸟哥这里也只是列出一些可能会用到的格式而已,有兴趣的话,可以自行多作一些测试与练习喔! ^_^
Tips: 列印格式化这个 printf 命令,乍看之下好像也没有什么很重要的~ 不过,如果你需要自行撰写一些软件,需要将一些数据在萤幕上头漂漂亮亮的输出的话, 那么 printf 可也是一个很棒的工具喔! |
awk:好用的数据处理工具
awk 也是一个非常棒的数据处理工具!相较於 sed 常常作用於一整个行的处理, awk 则比较倾向於一行当中分成数个『栏位』来处理。因此,awk 相当的适合处理小型的数据数据处理呢!awk 通常运行的模式是这样的:
[root@www ~]# awk '条件类型1{动作1} 条件类型2{动作2} ...' filename |
awk 后面接两个单引号并加上大括号 {} 来配置想要对数据进行的处理动作。 awk 可以处理后续接的文件,也可以读取来自前个命令的 standard output 。 但如前面说的, awk 主要是处理『每一行的栏位内的数据』,而默认的『栏位的分隔符号为 "空白键" 或 "[tab]键" 』!举例来说,我们用
last 可以将登陆者的数据取出来,结果如下所示:
[root@www ~]# last -n 5 <==仅取出前五行 |
若我想要取出帐号与登陆者的 IP ,且帐号与 IP 之间以 [tab] 隔开,则会变成这样:
[root@www ~]# last -n 5 | awk '{print $1 "\t" $3}' |
上表是 awk 最常使用的动作!透过 print 的功能将栏位数据列出来!栏位的分隔则以空白键或 [tab] 按键来隔开。 因为不论哪一行我都要处理,因此,就不需要有 "条件类型" 的限制!我所想要的是第一栏以及第三栏, 但是,第五行的内容怪怪的~这是因为数据格式的问题啊!所以罗~使用 awk 的时候,请先确认一下你的数据当中,如果是连续性的数据,请不要有空格或 [tab] 在内,否则,就会像这个例子这样,会发生误判喔!
另外,由上面这个例子你也会知道,在每一行的每个栏位都是有变量名称的,那就是 $1, $2... 等变量名称。以上面的例子来说, root 是 $1 ,因为他是第一栏嘛!至於 192.168.1.100 是第三栏, 所以他就是 $3 啦!后面以此类推~呵呵!还有个变量喔!那就是 $0 ,$0
代表『一整列数据』的意思~以上面的例子来说,第一行的 $0 代表的就是『root .... 』那一行啊! 由此可知,刚刚上面五行当中,整个 awk 的处理流程是:
- 读入第一行,并将第一行的数据填入 $0, $1, $2.... 等变量当中;
- 依据 "条件类型" 的限制,判断是否需要进行后面的 "动作";
- 做完所有的动作与条件类型;
- 若还有后续的『行』的数据,则重复上面 1~3 的步骤,直到所有的数据都读完为止。
经过这样的步骤,你会晓得, awk 是『以行为一次处理的单位』, 而『以栏位为最小的处理单位』。好了,那么
awk 怎么知道我到底这个数据有几行?有几栏呢?这就需要 awk 的内建变量的帮忙啦~
变量名称 | 代表意义 |
NF | 每一行 ($0) 拥有的栏位总数 |
NR | 目前 awk 所处理的是『第几行』数据 |
FS | 目前的分隔字节,默认是空白键 |
我们继续以上面 last -n 5 的例子来做说明,如果我想要:
- 列出每一行的帐号(就是 $1);
- 列出目前处理的行数(就是 awk 内的 NR 变量)
- 并且说明,该行有多少栏位(就是 awk 内的 NF 变量)
则可以这样:
Tips: 要注意喔,awk 后续的所有动作是以单引号『 ' 』括住的,由於单引号与双引号都必须是成对的, 所以, awk 的格式内容如果想要以 print 列印时,记得非变量的文字部分,包含上一小节printf 提到的格式中,都需要使用双引号来定义出来喔!因为单引号已经是 awk 的命令固定用法了! |
[root@www ~]# last -n 5| awk '{print $1 "\t lines: " NR "\t columns: " NF}' |
这样可以了解 NR 与 NF 的差别了吧?好了,底下来谈一谈所谓的 "条件类型" 了吧!
- awk 的逻辑运算字节
既然有需要用到 "条件" 的类别,自然就需要一些逻辑运算罗~例如底下这些:
运算单元 | 代表意义 |
> | 大於 |
< | 小於 |
>= | 大於或等於 |
<= | 小於或等於 |
== | 等於 |
!= | 不等於 |
值得注意的是那个『 == 』的符号,因为:
- 逻辑运算上面亦即所谓的大於、小於、等於等判断式上面,习惯上是以『 == 』来表示;
- 如果是直接给予一个值,例如变量配置时,就直接使用 = 而已。
好了,我们实际来运用一下逻辑判断吧!举例来说,在 /etc/passwd 当中是以冒号 ":" 来作为栏位的分隔, 该文件中第一栏位为帐号,第三栏位则是 UID。那假设我要查阅,第三栏小於 10 以下的数据,并且仅列出帐号与第三栏, 那么可以这样做:
[root@www ~]# cat /etc/passwd | \ |
有趣吧!不过,怎么第一行没有正确的显示出来呢?这是因为我们读入第一行的时候,那些变量 $1, $2... 默认还是以空白键为分隔的,所以虽然我们定义了 FS=":" 了, 但是却仅能在第二行后才开始生效。那么怎么办呢?我们可以预先配置 awk 的变量啊! 利用 BEGIN 这个关键字喔!这样做:
[root@www ~]# cat /etc/passwd | \ |
很有趣吧!而除了 BEGIN 之外,我们还有 END 呢!另外,如果要用 awk 来进行『计算功能』呢?以底下的例子来看, 假设我有一个薪资数据表档名为 pay.txt ,内容是这样的:
Name 1st 2nd 3th |
如何帮我计算每个人的总额呢?而且我还想要格式化输出喔!我们可以这样考虑:
- 第一行只是说明,所以第一行不要进行加总 (NR==1 时处理);
- 第二行以后就会有加总的情况出现 (NR>=2 以后处理)
[root@www ~]# cat pay.txt | \ |
上面的例子有几个重要事项应该要先说明的:
- awk 的命令间隔:所有 awk 的动作,亦即在 {} 内的动作,如果有需要多个命令辅助时,可利用分号『;』间隔, 或者直接以 [Enter] 按键来隔开每个命令,例如上面的范例中,鸟哥共按了三次 [enter] 喔!
- 逻辑运算当中,如果是『等於』的情况,则务必使用两个等号『==』!
- 格式化输出时,在 printf 的格式配置当中,务必加上 \n ,才能进行分行!
- 与 bash shell 的变量不同,在 awk 当中,变量可以直接使用,不需加上 $ 符号。
利用 awk 这个玩意儿,就可以帮我们处理很多日常工作了呢!真是好用的很~ 此外, awk 的输出格式当中,常常会以printf 来辅助,所以, 最好你对 printf 也稍微熟悉一下比较好啦!另外, awk 的动作内 {} 也是支持
if (条件) 的喔! 举例来说,上面的命令可以修订成为这样:
[root@www ~]# cat pay.txt | \ |
你可以仔细的比对一下上面两个输入有啥不同~从中去了解两种语法吧!我个人是比较倾向於使用第一种语法, 因为会比较有统一性啊! ^_^
除此之外, awk 还可以帮我们进行回圈计算喔!真是相当的好用!不过,那属於比较进阶的单独课程了, 我们这里就不再多加介绍。如果你有兴趣的话,请务必参考延伸阅读中的相关连结喔 (注4)。
文件比对工具
什么时候会用到文件的比对啊?通常是『同一个套装软件的不同版本之间,比较配置档与原始档的差异』。 很多时候所谓的文件比对,通常是用在 ASCII 纯文字档的比对上的!那么比对文件的命令有哪些?最常见的就是 diff 罗! 另外,除了 diff 比对之外,我们还可以藉由 cmp 来比对非纯文字档!同时,也能够藉由
diff 创建的分析档, 以处理补丁 (patch) 功能的文件呢!就来玩玩先!
- diff
diff 就是用在比对两个文件之间的差异的,并且是以行为单位来比对的!一般是用在 ASCII 纯文字档的比对上。 由於是以行为比对的单位,因此 diff 通常是用在同一的文件(或软件)的新旧版本差异上! 举例来说,假如我们要将 /etc/passwd 处理成为一个新的版本,处理方式为: 将第四行删除,第六行则取代成为『no
six line』,新的文件放置到 /tmp/test 里面,那么应该怎么做?
[root@www ~]# mkdir -p /tmp/test <==先创建测试用的目录 |
接下来讨论一下关於 diff 的用法吧!
[root@www ~]# diff [-bBi] from-file to-file |
用 diff 比对文件真的是很简单喔!不过,你不要用 diff 去比对两个完全不相干的文件,因为比不出个啥咚咚! 另外, diff 也可以比对整个目录下的差异喔!举例来说,我们想要了解一下不同的启动运行等级 (runlevel) 内容有啥不同?假设你已经知道运行等级 3 与 5 的启动脚本分别放置到 /etc/rc3.d 及 /etc/rc5.d , 则我们可以将两个目录比对一下:
[root@www ~]# diff /etc/rc3.d/ /etc/rc5.d/ |
我们的 diff 很聪明吧!还可以比对不同目录下的相同档名的内容,这样真的很方便喔~
- cmp
相对於 diff 的广泛用途, cmp 似乎就用的没有这么多了~ cmp 主要也是在比对两个文件,他主要利用『位组』单位去比对, 因此,当然也可以比对 binary file 罗~(还是要再提醒喔, diff 主要是以『行』为单位比对, cmp 则是以『位组』为单位去比对,这并不相同!)
[root@www ~]# cmp [-s] file1 file2 |
看到了吗?第一个发现的不同点在第四行,而且位组数是在第 106 个位组处!这个 cmp 也可以用来比对 binary 啦! ^_^
- patch
patch 这个命令与 diff 可是有密不可分的关系啊!我们前面提到,diff 可以用来分辨两个版本之间的差异, 举例来说,刚刚我们所创建的 passwd.old 及 passwd.new 之间就是两个不同版本的文件。 那么,如果要『升级』呢?就是『将旧的文件升级成为新的文件』时,应该要怎么做呢? 其实也不难啦!就是『先比较先旧版本的差异,并将差异档制作成为补丁档,再由补丁档升级旧文件』即可。
举例来说,我们可以这样做测试:
范例一:以 /tmp/test 内的 passwd.old 与 passwd.new 制作补丁文件 |
一般来说,使用 diff 制作出来的比较文件通常使用扩展名为 .patch 罗。至於内容就如同上面介绍的样子。 基本上就是以行为单位,看看哪边有一样与不一样的,找到一样的地方,然后将不一样的地方取代掉! 以上面表格为例,新文件看到 - 会删除,看到 + 会加入!好了,那么如何将旧的文件升级成为新的内容呢? 就是将 passwd.old 改成与 passwd.new 相同!可以这样做:
[root@www ~]# patch -pN < patch_file <==升级 |
为什么这里会使用 -p0 呢?因为我们在比对新旧版的数据时是在同一个目录下, 因此不需要减去目录啦!如果是使用整体目录比对 (diff 旧目录 新目录) 时, 就得要依据创建 patch 文件所在目录来进行目录的删减罗!
更详细的 patch 用法我们会在后续的第五篇的原始码编译 (第二十二章)再跟大家介绍, 这里仅是介绍给你,我们可以利用 diff 来比对两个文件之间的差异, 更可进一步利用这个功能来制作修补文件
(patch file) ,让大家更容易进行比对与升级呢!很不赖吧! ^_^
Linux学习之十六、文件的格式化与相关处理的更多相关文章
-
Linux学习(十四)磁盘格式化、磁盘挂载、手动增加swap空间
一.磁盘格式化 分好去的磁盘需要格式化之后才可以使用.磁盘分区一般用mke2fs命令或者mkfs.filesystemtype.这个filesystemtype分为ext4,ext3,xfs等等.xf ...
-
Linux学习之十六-Linux用户管理
Linux用户管理 Linux系统跟Windows系统一样,可以创建不同的用户,不同的用户组.在不同用户下使用系统具有相应的权限 创建一个普通用户时,会修改几个文件,拷贝一些初始文件到用户家目录中 修 ...
-
Linux学习(十六)VIM
一.简介 VIM是vi的增强版.VIM是Linux平台上的主要编辑器.基本上所有的文档的新增,修改,保存都需要用到它.所以,掌握VIM是很有必要的. vim的安装非常简单,一条命令就可以了: yum ...
-
Linux 常用命令十六 文件权限管理
一.ls -l 各段含义 wang@wang:~/workpalce/threading$ ls -l 总用量 drwxrwxr-x wang wang 12月 : a -rw-rw-r-- wang ...
-
学习笔记:CentOS7学习之十六:LVM管理和ssm存储管理器使用
目录 学习笔记:CentOS7学习之十六:LVM管理和ssm存储管理器使用 16.1 LVM的工作原理 16.1.1 LVM常用术语 16.1.2 LVM优点 16.2 创建LVM的基本步骤 16.2 ...
-
python3.4学习笔记(十六) windows下面安装easy_install和pip教程
python3.4学习笔记(十六) windows下面安装easy_install和pip教程 easy_install和pip都是用来下载安装Python一个公共资源库PyPI的相关资源包的 首先安 ...
-
风炫安全Web安全学习第十六节课 高权限sql注入getshell
风炫安全Web安全学习第十六节课 高权限sql注入getshell sql高权限getshell 前提条件: 需要知道目标网站绝对路径 目录具有写的权限 需要当前数据库用户开启了secure_file ...
-
Linux学习之十四、管线命令
Linux学习之十四.管线命令 地址:http://vbird.dic.ksu.edu.tw/linux_basic/0320bash_6.php
-
201671010140. 2016-2017-2 《Java程序设计》java学习第十六周
java学习第十六周-并发 本周,学习了Java中线程,并发的知识,在老师的带领下,进行了对知识的理解学习,以及对实验的运行讲解,对这一块内容掌握的还可以,在自主编程中,也能够完成.线, ...
随机推荐
-
Spring Aop实例
一.XML方式 1. TestAspect:切面类 package com.spring.aop; import org.aspectj.lang.JoinPoint; import org.aspe ...
-
perl环境配置以及Eclipse安装perl开发插件
简介: 这篇文章将详细介绍 EPIC 组件的安装,EPIC 编辑环境,调试运行环境,着重介绍如何使用 EPIC 来快速.简便.准确地调试 Perl 语言程序,包括对于 Perl 程序的单步执行,断点用 ...
-
.NET开发者需要的工具箱
本文作者 Spencer 是一名专注于 ASP.NET 和 C# 的程序员,他列举了平时工作.在家所使用的大部分开发工具,其中大部分工具都是集中于开发,当然也有一些其它用途的,比如图片处理.文件压缩等 ...
-
background-position 个人理解
background-position这里先说像素 百分比比较复杂background-position:xxpx xxpx 这里第一个值指的是x轴坐标 第二个值是y轴坐标这里使用的坐标系和数学 ...
-
砸金蛋:jQuery+PHP实现的砸金蛋中奖程序
原文 砸金蛋:jQuery+PHP实现的砸金蛋中奖程序 砸金蛋被广泛应用于庆典活动.商家促销.电视娱乐等场合,它的趣味.悬念能迅速活跃现场气氛.同样,我们也可以将砸金蛋应用到WEB网站上,用于开展线上 ...
-
SublimeText编辑器替代notepad++了
可以考虑使用SublimeText编辑器替代notepad++了 内容目录: 插件安装配置 配置打包下载 大概是去年吧,这款编辑器神一般的出现在我面前,经过我小心翼翼的试用后发现并不是那么太顺手, ...
-
Spring读取外部属性-properties
概述 在Spring中处理外部值最简常用的方法就是外部创建name.properties文件,并在其中声明变量值,供Java进行读取.比如数据源信息配置,Java固定属性位置等.读取的方式一般由三种: ...
-
ES 06 - 通过Kibana插件增删改查ES中的索引文档
目录 1 document的结构 2 document的常见CRUD操作 2.1 添加商品: 添加文档并建立索引 2.2 查询商品: 检索文档 2.3 修改商品: 替换文档 2.4 修改商品: 更新文 ...
-
loadrunner11迭代录制注册账号
1.创建一个新的web脚本 2.我们就以loadrunner自带的WebTours为例子 3.点击确定后进入Web Tours主页,点击sign up now进行注册 4.输入用户名:test,密码: ...
-
Linux基础(四)网络设置
环境: linux系统版本为:CentOS 7 虚拟机:vm12 共享本地计算机网络,达到我们linux系统上网的目的 虚拟机,添加网卡-设置 设置成,自定义vmnet8 NAT模式即可,不需要添加什 ...