Shell 编程拾锦

awk 工具

以相同的列首字段分割文件

需求

文件的第一列为分类标志,以相同的每行第一列内容为分隔,将文件分为不同的多个文件。

实现

假设有文件 “run” 内容如下:

1
2
3
4
5
6
7
8
0 one
0 two
1 three
1 four
1 five
2 six
2 seven
2 eigth

首先,需要一个变量 fs 来记录每相同首列部分的首列内容,在 BEGIN 阶段需要对此变量初始化,在判断出 fs 与当前行的首列内容 $1 不同时重新给 fs 赋值并创建新文件;同时,还需要一个变量 fn 记录不同部分对应的输出文件名。具体实现为:

1
2
3
4
5
6
7
8
9
10
11
12
[user@A ~]$ cat run | awk 'BEGIN {fs=""} {if(fs!=$1) {fs=$1; fn="file" $1; print $1, $2 > fn} else {print $1, $2 >> fn}}'
[user@A ~]$ cat file0
0 one
0 two
[user@A ~]$ cat file1
1 three
1 four
1 five
[user@A ~]$ cat file2
2 six
2 seven
2 eigth

同模式重复多行块重组

需求

文件按同一模式多行重复不同对象的内容,现需要将同一对象的信息以同一行内容保存。

实现

假设有文件 “run” 内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
学号
姓名
年龄
成绩
200101
张三
18
74
200102
李四
17
39
200103
王二
19
56

可见,该文件以每四行分别为“学号”、“姓名”、“年龄”和“成绩”内容的模式呈多行重复,这里要将每四行重新整合为一行,借助内置变量已读记录数 NR 和输出记录分隔符 ORS ,可以如下命令实现:

1
2
3
4
5
[user@A ~]$ cat run | awk '{if(NR%4!=0) ORS=" "; else ORS="\n"; print $0}'                                                          
学号 姓名 年龄 成绩
200101 张三 18 74
200102 李四 17 39
200103 王二 19 56

sed 工具

修改配置文件中的某一关键行

需求

文件主要以多行“键名 键值”的形式作为多参数配置文件存在,现需要根据指定键名修改其对应的键值。

实现

假设有配置文件 input.conf 如下:

1
2
3
4
5
6
model_file = 'model.dat'
output_prefix = 'out'
transform_into_xyz = T

record_time_length = 10.0
record_time_step = 0.005

如欲快速修改 model_file 键名的值为 new.dat,可以如下命令实现

1
2
3
4
5
6
7
[user@A ~]$ sed "/model_file/s/=.*/= 'new.dat'/g" input.conf
model_file = 'new.dat'
output_prefix = 'out'
transform_into_xyz = T

record_time_length = 10.0
record_time_step = 0.005

其中,/model_file 表示匹配以 model_file 开头的行,/=.* 表示匹配等号及其后所有内容。

---------- 文结至此 静待下章 ----------