微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

使用tac来反向读取文件

对于UNIX编码,我是相当新的,我有一个文件,我需要逐行反向读取。 该文件在{}中包含代码部分。 然后我需要用这个反转文件作为input运行一个awk脚本。 我有我们的支持人员安装TAC,但在他们之前,我想知道它是否会输出我所需要的,或者如果有人可以build议一个替代。

文件具有以下格式的数据:

page 0 0 0 none { layer 0 0 0 "1line" 0 8 8 3 { sector 0 -1 0 32 { point_name 0 0 34543 34 44 1 1 0 status 1 0 1 0 1 431232 "transformer" 23 12 analog 1 0 1 0 1 321234 11.5 43 1 1 0 ... ... ... device 1 0 1 "ground" 32 56 1 1 0 } } }

我想保留{},但将{}之间的界限颠倒过来,这样看起来像:

page 0 0 0 none { layer 0 0 0 "1line" 0 8 8 3 { sector 0 -1 0 32 { device 1 0 1 "ground" 32 56 1 1 0 ... ... ... analog 1 0 1 0 1 321234 11.5 43 1 1 0 status 1 0 1 0 1 431232 "transformer" 23 12 point_name 0 0 34543 34 44 1 1 0 } } }

另外,tac覆盖input文件还是将其另存为另一个文件

redirect文件到标准输出 – 反向ioredirect

Nginx和反向代理的http_sub_module / sub_filter不起作用

如何find没有任何符号信息的elf可执行文件的主函数的入口点?

带有基本authentication的Apache反向代理

Nginx反向代理设置

Windows日志文件查看器(尾),显示相反的顺序行

像大多数UNIX (样式)工具一样, tac既不会覆盖原文件,也不会写入新文件,而是打印到stdout ,用tac写一个文件,您可以使用tac file > newfile来保存反转file 。 你不能单独用tac来做你需要的东西,你需要一个脚本。

这里是awk一个

{ # store each line in the array line line[n++] = $0 } /{/ { # get the line number of the last line containing { first=NR } !/}/ { # get the line number of the last line not containing } last=NR } END { # print first section in order for (i=0;i<first;i++) print line[i] # print second section in reverse order for (i=last-1;i>=first;i--) print line[i] # print last section in order for (i=last;i<NR;i++) print line[i] }

保存到一个文件说reverse然后运行awk -f reverse file :

$ awk -f reverse file page 0 0 0 none { layer 0 0 0 "1line" 0 8 8 3 { sector 0 -1 0 32 { device 1 0 1 "ground" 32 56 1 1 0 ... ... ... analog 1 0 1 0 1 321234 11.5 43 1 1 0 status 1 0 1 0 1 431232 "transformer" 23 12 point_name 0 0 34543 34 44 1 1 0 } } }

使用重定向来创建一个文件awk -f reverse file > newfile 。

tac简单地反转文件的行顺序,因此您需要更强大的功能来完成您想要的功能。 另外,所有shell工具都不包含覆盖输入文件方法,而不使用“temp”文件。 一些工具(例如sed , Perl等)具有所谓的“就地编辑”选项,即当没有提供备份文件后缀时,会给出文件覆盖的最终结果。

为了完成你想要的,我建议使用awk 。 运行如下:

awk -f script.awk file > newfile

要使用临时文件覆盖输入文件,请运行:

awk -f script.awk file > temp && mv temp file

script.awk内容

/{/ { print (a ? a ORS : "") $0 f=1; a=b="" next } f && !/}/ { a = (a ? a ORS : "") $0 b = $0 (b ? ORS b : "") next } /}/ && b { print b ORS $0 a=b=f="" next }1

结果:

page 0 0 0 none { layer 0 0 0 "1line" 0 8 8 3 { sector 0 -1 0 32 { device 1 0 1 "ground" 32 56 1 1 0 ... ... ... analog 1 0 1 0 1 321234 11.5 43 1 1 0 status 1 0 1 0 1 431232 "transformer" 23 12 point_name 0 0 34543 34 44 1 1 0 } } }

另外,这里是一个班轮:

awk '/{/ { print (a ? a ORS : "") $0; f=1; a=b=""; next } f && !/}/ { a = (a ? a ORS : "") $0; b = $0 (b ? ORS b : ""); next } /}/ && b { print b ORS $0; a=b=f=""; next }1' file

说明:

一个代码块询问该行是否包含左大括号。 如果是这样,打印记录“a”后面跟着当前记录(包含大括号的行)的任何内容。 设置一个标志,删除记录“a”和“b”,并跳过处理其余的代码

当且仅当该标志已被设置且该行不包含闭合大括号时,才会执行第二个块。 现在我们建立两个记录“a”和“b”。 回想一下,如果一条线包含一个大括号,记录“a”将被打印出来。 所以它必须建立在“从头到尾”的方向上。 然后,我们在“结束开始”方向建立记录“b”。 'next'然后跳过处理其余的代码

如果该行包含一个右大括号和记录“b”(记得这是相反方向的记录构建),则将执行第三个块。 然后,我们打印记录“b”,然后打印当前行(带大括号的行)。 删除记录“a”,“b”并重置标记。 '下一步'跳过处理其余的代码。 最后的'1'启用认打印。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐