sed - 跨行匹配模式
问题描述
假设我有一个文件,其中包含:
something
line=1
file=2
other
lines
ignore
something
line=2
file=3
other
lines
ignore
最终,我想要每个部分中的行和文件组合的唯一列表。在第一阶段,我试图将sed
那些组合成一行的行输出,比如
line=1file=2
line=2file=3
然后我可以使用sort
and uniq
。
所以我正在尝试
sed -n -r 's/(line=)(.*?)(\r)(file=)(.*?)(\r)/\1\2\4\5/p' sample.txt
(不一定只是每个后面的数字)
但它不会跨界匹配。我试过 \n 和 \r\n 但它似乎不是换行的风格,因为:
sed -n -r 's/(line=)(.*?)(\r)/\1\2/p' sample.txt
将输出“line =”行,但我无法让它跨越新行,并收集第二行。
解决方案
默认情况下,sed
只会对由\n
字符分隔的块进行操作,因此您永远不能跨多行匹配。一些sed
实现支持-z
选项,它将使其对由 ASCII NUL 字符而不是换行符分隔的块进行操作(这可能适用于小文件,假设 NUL 字符不会影响您要匹配的模式)
还有一些sed
命令可以用于多行处理
sed -n '/line=/{N;s/\n//p}'
N
命令将下一行添加到当前正在处理的块(line=
在这种情况下必须匹配)s/\n//p
然后删除换行符,以便您将输出作为单行
如果您的输入具有 dos 样式行结尾,请先将其转换为 unix 样式(请参阅为什么我的工具输出会覆盖自身以及如何修复它?)或\r
同时处理
sed -n '/line=/{N;s/\r\n//p}'
请注意,这些命令已经过测试GNU sed
,其他实现的语法可能会有所不同
推荐阅读
- c# - 如何将 ListBox 项写入文本文件?
- python - super().__repr__() 和 repr(super()) 有什么区别?
- java - JPA和Hibernate实体的列表属性中的重复项
- postgresql - AWS RDS postgresql 9.4 上的 template0 数据库上的 Autovacuum
- conditional - 始终显示为“失败”
- ios - 将字符串从 JSON 数据发送到函数外部的变量
- python - Python - 只能在两个关键字列表中检测到关键字时发送消息?
- css - 祖先内类型的第一个后代的 CSS 选择器
- spark-structured-streaming - 如何在 Spark 的结构化流中创建 RDD?
- c# - 反序列化 JSON 中的两个元素字符串