怎么对一个文本进行格式化操作?如果使用的是windows,那么你的弄好半天,可是在linux上,我只能说so easy。对awk就敢这么说。超级强大
awk
不仅是一个命令,还是一门编程语言,能够实现条件判断,数组,循环等功能。以行为单位处理,将每一行以指定的分隔符分为多个分段,取出所需分段,以指定分隔符输出。
语法: 1 2 # 第一种:program被单引号包围 awk [option] ‘program’ file
1 2 # 第二种:分为模式和动作 awk [option] 'pattern option' file
awk
的两种写法中最常用的是第二种。
各部分参数 option常用选项:
1 2 -F #define input field separator by extended regex,指定分隔符。容易记错,所以还是用-v FS=''指定内部变量比较好。 -v #assign values to variables,使用内部、外部变量。几乎每个awk命令都会用的一个参数
awk内置变量 1 2 3 4 5 6 7 8 9 FS field separate ,输入字段分隔符,默认为空白字符 OFS output field separate,输出字段分隔符,默认为空白字符 RS record separate,输入记录分隔符,每一条记录(row)分隔的依据,默认为回车 ORS output record separate,输出记录分隔符,可以将多行合并为一行 NF number of field,字段数,$NF为最后一行 NR number of record,记录数(row),可以跟多个文件,文件的记录连续 FNR 可以跟多个文件,第二个文件记录数从一开始 ARGC 命令行参数个数 ARGV 命令行各参数组成的数组
例子:使用内部变量,指定输入字段分隔符
1 awk -v FS=':' '{print $1}' /etc/passwd
将多行合并为一行
1 awk -v ORS='' '{print $0}' /etc/passwd
使用外部变量
1 awk -v h=$HOST BEGIN'{print h}' #BEGIN用来初始化变量
printf格式化输出 1 awk -v FS=':' '{printf "%-30s %-20s %-10s\n",$1,$2,$3}' /etc/passwd
%
表示格式化输出
-
减号表示左对齐,后面的数字表示变量所占用的宽度,变量没有占完的宽度用空白字符替代,可以实现真正的格式化输出
+
加号表示右对齐。
\n
printf不会自动换行,需要手动加上
1 2 3 4 5 6 7 8 % c: 显示字符的ASCII码 % d %i: 显示十进制整数 % e %E: 显示科学计数法数值 % f :显示为浮点数,小数 %5.1f,带整数、小数点、整数共5位,小数1位,不够用空格补上 % g %G :以科学计数法或浮点形式显示数值 % s :显示字符串;例:%5s最少5个字符,不够用空格补上,超过5个还继续显示 % u :无符号整数 % %: 显示% 自身
操作符 算数操作符
赋值操作符
比较操作符
逻辑操作符
模式匹配操作符
三目操作符 1 selector?if-true-expression:if-false-expression
函数调用
awk语句 除了指定一些变量外,其余内容的都应该写到括号里面,作为语句的一部分。awk的语法与c语言类似,语句间用分号相隔,同时变量不需要像shell中一样加$,直接使用变量名就行。语句块使用{}
if语句
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 --- ~ » seq 10 | paste -s | awk '{if($3>2) print $0}' 1 2 3 4 5 6 7 8 9 10 --- ~ » seq 10 | paste -s | awk '{if($3<2){print $3} else if($4<3){print $4} else{print $5}}' 5 --- ~ » seq 10 | paste -s | awk '{if($3<2){ pipe pipe quote> print $3 pipe pipe quote> } pipe pipe quote> else if($4<3){ pipe pipe quote> print $4 pipe pipe quote> } pipe pipe quote> else{ pipe pipe quote> print $5 pipe pipe quote> } pipe pipe quote> }‘ 5
while循环
1 2 --- ~ » awk 'BEGIN{sum=0;i=1;while(i<=100){sum+=i;i++};print sum}' 5050
for循环
1 2 --- ~ » awk 'BEGIN{sum=0;for(i=1;i<=100;i++){sum+=i};print sum}' 5050
tips:awk循环中还可以使用break,continue,next等控制循环
至于其它功能,我觉得用处不大,所以不写了,有以上这些足够了。