我们有以下文件,其中一堆感兴趣的记录(百万条记录)位于模式的开始和结束之间。开始模式始终以 A 开头,结束模式始终以 Z 开头。
Apattern1 somethinghere #start of pattern always starts with A
Line-of-data-here-aaa
Line-of-data-here-xxxxx
Zpattern1 #end of pattern always starts with Z
ApatternX somethinghere #Repeat: start of pattern always starts with A
Line-of-data-here-bbbb
Line-of-data-here-yyyy
Line-of-data-here-nnnnn
ZpatternX
我们希望通过将起始模式(整行)附加到模式内的行来转换数据。我们想要删除末端图案。我们希望使用 sed 和/或 awk 将模式开头(以 A 开头)的行附加到模式内的行(以 L 开头)并删除模式的结尾(始终以 Z 开头),因此数据文件将如下所示:
Apattern1 somethinghere Line-of-data-here-aaa
Apattern1 somethinghere Line-of-data-here-xxxxx
ApatternX somethinghere Line-of-data-here-bbbb
ApatternX somethinghere Line-of-data-here-yyyy
ApatternX somethinghere Line-of-data-here-nnnnn
答案1
据我了解您的问题,您要问的是:
sed -E '/^A/h;/^[AZ]/d;G;s/(.*)\n(.*)/\2 \1/' yourfile
因此,以 或 开头的行将A
被复制到保留空间 ( /^A/h
),然后以 或 开头的行将被删除A
,Z
因为我们不想打印它们 ( /^[AZ]/d
)。对于所有其他行,该行的保留空间A
将被附加 ( G
),两个部分将通过空格而不是换行符 ( s/(.*)\n(.*)/\2 \1/
)进行交换
sed
(我自己做的扩展更容易一些:\h
在替换中扩展到保留缓冲区的内容:
sed -E '/^A/h;/^[AZ]/d;G;s/^/\h /' yourfile
如果我遇到更多这样的问题,我会提出合并请求。)
答案2
sed -e '
/^A/,/^Z/!d
//{h;d;}
G;s/\(.*\)\n\(.*\)/\2\t\1/
' yourfile
结果:
Apattern1 somethinghere Line-of-data-here-aaa
Apattern1 somethinghere Line-of-data-here-xxxxx
ApatternX somethinghere Line-of-data-here-bbbb
ApatternX somethinghere Line-of-data-here-yyyy
ApatternX somethinghere Line-of-data-here-nnnnn
解释
- 通过拒绝不正确的范围来选择正确的范围:'/^A/,/^Z/!d'
- 将范围边界存储在保留空间中。
- 范围内部,将保留附加到当前行并翻转 + 将 \n 更改为制表符。