linux - 如何在拖尾文件时每隔“n”个空格插入空格或字符?
问题描述
我正在跟踪一个日志文件,并希望使其更具可读性。
当前的输出是这样的:
HH:MM:SS.ss CONTROL:00011100001110101010111000000000
HH:MM:SS.ss INDICATION:00000001110101001111010101011011
我希望输出更像这样:
HH:MM:SS.ss CONTROL:00011100 00111010 10101110 00000000
HH:MM:SS.ss INDICATION:00000001 11010100 11110101 01011011
如果sed
可以用来插入空格,那就太好了。
空格必须是每 8 个字符 - 它总是在最后一个:
八位字节之后的二进制数据中(但八位字节缺少我想看到的空格)。
解决方案
此代码适用于 GNU 和 BSD (macOS) 版本sed
:
sed -e ':a' -e 's/^\(.*:\([01]\{8\} \)*\)\([01]\{8\}\)\([^ ]\)/\1\3 \4/' -e 't a'
给定数据文件:
HH:MM:SS.ss CONTROL:00011100001110101010111000000000
HH:MM:SS.ss INDICATION:00000001110101001111010101011011
17:49:23.96 MODIFIED:0100010010101010101101010101010101001010101010111110100010011101
它给出了输出:
HH:MM:SS.ss CONTROL:00011100 00111010 10101110 00000000
HH:MM:SS.ss INDICATION:00000001 11010100 11110101 01011011
17:49:23.96 MODIFIED:01000100 10101010 10110101 01010101 01001010 10101011 11101000 10011101
第一个-e
命令创建一个标签a
;a
如果中间的命令进行了替换,第三个跳转到标签(这是一个循环sed
)。乐趣在于中间的命令:
s/^\(.*:\([01]\{8\} \)*\)\([01]\{8\}\)\([^ ]\)/\1\3 \4/
该\(…\)
符号捕获可以\n
在替换子句中引用的信息。他们也可以筑巢。需要前一个单元的\{8\}
8 个(在这种情况下)。前面的单位是[01]
,二进制数。
总的来说,它捕获到最后一个冒号:
加上 0 个或更多单元的 8 个二进制数字,后跟一个空格(并将所有这些捕获为\1
;其中还有一个\2
,但我不使用它),加上一个单元 8二进制数字(捕获为\3
)后跟一个非空白(捕获为\4
)。它将它们替换为\1\3 \4
.
因为\4
需要成为下一个 8 位二进制数字序列的一部分,所以您需要循环而不是g
替换命令上的修饰符。
FWIW:我将代码写在一个文件sed.script
中,其中包含:
:a
s/^\(.*:\([01]\{8\} \)*\)\([01]\{8\}\)\([^ ]\)/\1\3 \4/
t a
然后跑:
sed -f sed.script data
这有时可能是一种有用的技术。在这里,它并不重要,但它可以简化生活,尤其是当您需要在 sed 脚本中处理引号(单引号、双引号、反引号)时。该文件不受解释正则表达式内容的 shell 的影响。
推荐阅读
- php - 如何使用 PHP 删除文件中的前 11 行?
- angular - 无法在 Angular 6 项目中使用 Karma-jasmine 测试工具测试动态内容
- qt - 如何将 Q_ENUM 转换为 QString 对于 QT > 5.11 最有效的方式?
- angular - Angular 库 - 'rootDir' 应该包含所有源文件。(环境.ts)
- javascript - 使用 Ajax 从不同的输入上传多个文件
- c# - 与方法组相比委托实例分配
- amazon-web-services - 具有多个值的 amazon lex 插槽类型
- winforms - PowerShell:复制具有不同属性的窗体
- java - 在图像视图中分别设置两个来自相机的裁剪图像(Android Studio)
- reactjs - 可以访问 React 组件状态的样式化组件?