问题描述
昨天,一位群友在群里面问如何使用 sed 生成目标格式的问题。问题的详细描述如下:
一个文件中有多行数据,每一行数据的格式如下:
a b c d
x y
输出数据格式如下:
a_B b_I c_I d_E
v_B g_E
解决方案
通过对输入与输出的分析,不难看出开头的一个字段要添加 _B 后缀,中间字段添加 _I 后缀,末尾字段添加 _E 后缀。这种格式转换使用 sed 的话相对麻烦,因此我先使用 awk 解决了这个问题。
使用的 awk 脚本内容如下:
{
if ($0 ~ /^$/)
next
if (NF == 1) {
printf("%s_B\n", $1)
} else if (NF == 2) {
printf("%s_B ", $1)
printf("%s_E\n", $2)
} else {
printf("%s_B ", $1)
for (i = 2; i < NF; i++) {
printf("%s_I ", $i)
}
printf("%s_E\n", $NF)
}
}
将上述脚本保存为 make.suffix.awk 文件,使用 gawk -f make.suffix.awk filename 执行。
测试使用的输入文件的内容如下:
a b c d
x y
x y z
a b c d e g e
x
y
x z
z x
执行结果如下:
[longyu@debian:09:39:26] awk $ gawk -f make_suffix.awk data
a_B b_I c_I d_E
x_B y_E
x_B y_I z_E
a_B b_I c_I d_I e_I g_I e_E
x_B
y_B
x_B z_E
z_B x_E
sed 如何解决
使用 sed 也能够解决这个问题。这里使用的 sed 脚本内容如下:
/.*/{
s/\([[:alpha:]]\{1,\}\) /\1_I /g
s/[[:alpha:]]\{1,\}$/&_E/
s/\(^[[:alpha:]]\{1,\}\)_[IE]/\1_B/
}
执行示例如下:
[longyu@debian:09:46:29] awk $ sed -f sedsrc-make-suffix.sed data
a_B b_I c_I d_E
x_B y_E
x_B y_I z_E
a_B b_I c_I d_I e_I g_I e_E
x_B
y_B
x_B z_E
z_B x_E
首先在所有的单词后面追加 _I,然后先处理结尾的 _E,最后替换行首的单词即可。