我有这个AWK脚本用5个换行符替换每个换页符(0x0C,12):
f=${*:-"-"}
awk 'BEGIN {FF=sprintf("%c",12); LF=sprintf("\n\n\n\n\n")}
{i1=0;for(i2=i1+1;i2<=length($0);i2++) if(substr($0,i2,1) == FF)
{print substr($0,i1+1,i2-i1-1) LF; i1=i2}
print substr($0,i1+1,length($0)-i1)}' $f
现在我要做的是在文件中替换此符号的仅最后一次出现。想不出一个直截了当的解决方案。如何检测最后一行?有什么想法吗?
AWK更可取(性能问题)。
答案 0 :(得分:1)
sed '/\f/!b;:a;$!N;/\n.*\f/{h;s/\n[^\n]*$//p;s/^.*\n//;};$!ba;s/^\(.*\)\f/\1\n\n\n\n\n/' inputfile
说明:
/\f/!b
- 如果该行不包含FF,则分支到结尾并打印:a
- 标签“a”
$!N
- 如果不是最后一行,则追加下一行/\n.*\f/{
- 如果新添加的行中有FF,则
h
- 将累积的行保存在保留空间s/\n[^\n]*$//p
- 删除最后累积的行并打印其余部分g
- 从保留空间恢复累积的行数s/^.*\n//
- 删除除最后累积的行之外的所有内容}
- 如果$!ba
- 如果不是最后一行,请分支到标签“a”s/^\(.*\)\f/\1\n\n\n\n\n/
- 用五个换行符替换文件中的最后一个FF 请注意,即使最后一行不在最后一行,这仍然有效。
以下是如何在AWK中执行此操作:
awk '/\f/ {
print accum;
accum = $0;
next
}
{
accum = accum "\n" $0
}
END {
match(accum, ".*\f");
print substr(accum, 1, RLENGTH - 1) "\n\n\n\n\n" substr(accum, RLENGTH + 1)}'
}' inputfile
它只记忆它必须的东西。
答案 1 :(得分:0)
我不知道awk
足以做到这一点,但可以使用sed
:
sed -e '$s/\x0C$/\x0C\x0C\x0C\x0C\x0C/' your_file
\x0C
代表ascii十六进制代码0C的字符,你可能已经猜到了。
如果要修改文件上的文件,而不是将脚本的结果转储到标准输出,请添加-i
参数。
答案 2 :(得分:0)
这是一个perl单行程序,它将整个内容读入内存并替换最后一个回车符:
perl -0777 -pe 's{\r([^\r]*)\z}{\n\n\n\n\n\1}' "$f"
或
perl -0777 -pe '
$pos = rindex($_, "\r");
substr($_, $pos, 1) = "\n\n\n\n\n" if $pos != -1
' "$f"