普通的行处理任务用sed很好。
awk最好的部分是它按“列”或“字段”处理的方式和“关联数组”,但awk对正则表达式支持的程度比sed要差些。
以下主要参考于:
9.sed流编辑器
sed并不与初始化文件打交道,它操作的只是一个拷贝,然后所有的改动如果没有重定向到一个文件,将输出到屏幕。
sed 的編輯指令均由位址(address)與函數(function)兩部份組成 , 其中 , 在執行時 , sed 利用它的位址參數來決定編輯的對象;而用它的函數參數編輯。
9.0 调用sed命令有两种形式:
一般形式:
sed SCRIPT INPUTFILE...
完整形式:
sed OPTIONS... [SCRIPT] [INPUTFILE...]
更浅显的形式:
sed [options] 'command' file(s)
sed [options] -f scriptfile file(s)
9.1将oldfile中的day,替换为新文件中的night。
sed ‘s/day/night/’ newfile
sed ‘s/day/night/’ oldfile >newfile
9.2将文件每行末尾添加,
sed s/$/,/ change_config_name.bak
9.3 将行首添加'单引号。
sed "s/^/'/" new
9.4 将行首添加单引号',行尾添加单引号和逗号',。
-e参数使得可以执行多个操作
sed -e "s/^/'/" -e "s/$/',/" new
9.5 sed命令中的定界符/,可以用其他的,不一定为/
9.6 echo "123123123" | sed 's/123/abc/',只替换第一个123为abc,
如果都替换的话,需要加入/g,如下:
echo "123123123" | sed 's/123/abc/g'
9.7 echo "34561" | sed 's/1*/abc/g'
结果为:
abc3abc4abc5abc6abc
有些费解啊!细想想也对,我们用"-"代表什么也没有,那么
-3-4-5-6-1-字符串的"-"符合1*匹配。
9.8 字符&代表匹配的字符串。
9.9 \1 可以保留部分匹配的结果。
9.10 d命令参数的使用:
删除含有'/*'和'--'的行,以下regex并不很严密。
sed -e "/\/\*/d" -e "/--/d" your.sql > your_bak.sql
|
删除不匹配的行:
sed '/^\[/ !d' 2010-05-28 > jacky
sed 常用正则表达式:
sed '1,/^$/ d' 以下主要摘自gnu sed manual
关于sed的正则表达式:
(1)对于一些特殊字符("?","+",...),在正则表达式中需要使用"\" ;
(2) 星"*"一般只管它前面的字符。
(3) '[a-zA-Z0-9]'
In the C locale, this matches any
10. awk用法
10.1 前言
10.2 awk概述
可以考虑用awk写程序的某一小部分,实现功能,若有效率问题,再用c改写优化。 数据行 字段 字段分割符FS
10.3如何执行awk
10.3.1
$awk 'awk程序' 数据文件文件名
awk程序的主要结构:
Pattern { Actions}
常见之awk 程序其型态如下 :
Pattern1 { Actions1 }
Pattern2 { Actions2 }
......
Pattern3 { Actions3 }
Pattern: "关系表达式"(Relational expression)
Actions: 由许多awk指令构成. 而awk的指令与 C 语言中的指令十分类似.
awk 会先判断(Evaluate) 该 Pattern 的值, 若
Pattern 判断后的值为true
(或不为0的数字,或不是空的字符串), 则 awk将执行该 Pattern 所对应的 Actions.反之, 若 Pattern 之值不为 true, 则awk将不执行该 Pattern所对应的 Actions.
Pattern { Actions }中, Pattern 部分被省略,只剩
{Actions}.这种情形表示
"无条件执行这个
Actions".
10.3.2 awk 所内建的字段变量及其涵意如下 :
字段变量
|
含义
|
$0
|
一字符串,
其内容为目前 awk 所读入的数据行.
|
$1
|
$0 上第一个字段的数据.
|
$2
|
$0 上第二个字段的数据.
|
...
|
其余类推
|
10.3.3awk的内建变量(Built-in Variables)
awk 提供了许多内建变量, 使用者于程序中可使用这些变量来取得相关信息.常见的内建变量有 :
内建变量
|
含义
|
NF (Number of Fields)
|
为一整数,
其值表$0上所存在的字段数目.
|
NR (Number of Records)
|
为一整数,
其值表awk已读入的数据行数目.
|
FILENAME
|
正在处理的数据文件文件名.
|
10.3.4 awk的工作流程:
执行awk时, 它会反复进行下列四步骤.
1.自动从指定的数据文件中读取一个数据行.
2.自动更新(Update)相关的内建变量之值. 如 : NF, NR, $0...
3.依次执行程序中 所有 的 Pattern { Actions } 指令.
4.当执行完程序中所有 Pattern { Actions } 时, 若数据文件中还有未读取的数据, 则反复执行步骤1到步骤4.
awk会自动重复进行上述4个步骤, 使用者不须于程序中编写这个循环 (Loop)
10.3.5 awk的数组
10.3.6
重定向(> >>)在awk中使用时,要么都用>> 要么都用>,如果混合使用,有些版本的awk会出问题。
10.3.7 awk 利用系统资源,与系统交互:
[a. 语法] awk output 指令 | "Shell 接受的命令"
( 如 : print $1,$2 | "sort -k 1" )
[b. 语法] "Shell 接受的命令" | awk input 指令
( 如 : "ls " | getline)
注 : awk input 指令只有 getline 一个.
awk output 指令有 print, printf() 二个.
注意:awk提供另一个调用Shell命令的方法, 即使用awk函数system("shell命令")
例如:
$ awk '
BEGIN{
system("date > date.dat")
getline < "date.dat"
print "Today is ", $2, $3
}
'
但使用 system( "shell 命令" ) 时, awk无法直接将执行中的部分数据输出给Shell 命令. 且 Shell 命令执行的结果也无法直接输入到awk中.
10.3.8 awk程序的执行方式:
若欲执行该awk程序, 来印出文件 today_rpt1 及 today_rpt2 的内容时,
必须于 UNIX 的命令行上执行下列命令 :
方式一 awk -f mydump.awk today_rpt1 today_rpt2
方式二 awk '{print}' today_rpt1 today_rpt2第二种方式系将awk 程序直接写在 Shell 的命令行上, 这种方式仅适合较短的awk程序.
方式三 建立如下之 shell script, 并取名为 mydisplay,
#!/bin/sh
# 注意以下的 awk 与 ' 之间须有空白隔开
awk '
{print}
' $*
# 注意以上的 ' 与 $* 之间须有空白隔开
[ 说 明 : ]
在script文件 mydisplay 中, 指令"awk"与第一个 ' 之间须有空格(Shell中并无" awk' "指令).
第一个 ' 用以通知 Shell 其后为awk程序.
第二个 ' 则表示 awk 程序结束.
故awk程序中一律以"括住字符串或字符, 而不使用 ' , 以免Shell混淆.
$* 为 shell script中的用法, 它可用来代表命令行上 "mydisplay之后的所有参数".
例如执行 :
$ mydisplay today_rpt1 today_rpt2
事实上 Shell 已先把该指令转换成 :
awk '
{ print}
' today_rpt1 today_rpt2
本例中, $* 用以代表 "today_rpt1 today_rpt2". 在Shell的语法中, 可用 $1 代表第一个参数, $2 代表第二个参数. 当不确定命令行上的参数个数时, 可使用 $* 表之.
10.3.9 改变 awk 切割字段的方式:
FS = "[ \t:]+" (注: [ \t:]+ 为一Regular Expression )
Regular Expression 中使用中括号 [ ... ] 表示一个字符集合,用以表示任意一个位于两中括号间的字符.故可用"[ \t:]"表示 一个 空白 , tab 或 ":"
Regular Expression中使用 "+" 形容其前方的字符可出现一次
阅读(933) | 评论(0) | 转发(0) |