繁体   English   中英

正则表达式模式匹配两行-搜索和替换

[英]regex Pattern Matching over two lines - search and replace

我有一个需要帮助的文本文档。 在下面的示例中,以制表符分隔的文本doc的摘录形式显示,其中3线模式的第一行将始终为数字。 该文档将始终采用这种格式,并且三行中的每一行都具有相同的选项卡式公式。

nnnn **variable** V -------
* FROM CLIP NAME - **variable**
* LOC: variable variable **variable**

我想将第一行的第二个字段替换为第三行的第四个字段。 然后将第二行中冒号后面的字段替换为第一行中原始的第二个字段。 正则表达式可能吗? 我习惯于单行搜索替换功能,但不习惯多行模式。

000003  A009C001_151210_R6XO             V     C        11:21:12:17 11:21:57:14 01:00:18:22 01:01:03:19 
*FROM CLIP NAME:  5-1A 
*LOC: 01:00:42:15 WHITE   005_NST_010_E02 
000004  B008C001_151210_R55E             V     C        11:21:18:09 11:21:53:07 01:01:03:19 01:01:38:17 
*FROM CLIP NAME:  5-1B 
*LOC: 01:01:20:14 WHITE   005_NST_010_E03

结果看起来像:

000003  005_NST_010_E02             V     C        11:21:12:17 11:21:57:14 01:00:18:22 01:01:03:19 
*FROM CLIP NAME:  A009C001_151210_R6XO
*LOC: 01:00:42:15 WHITE   005_NST_010_E02 
000004  005_NST_010_E03             V     C        11:21:18:09 11:21:53:07 01:01:03:19 01:01:38:17 
*FROM CLIP NAME:  B008C001_151210_R55E 
*LOC: 01:01:20:14 WHITE   005_NST_010_E03

提前谢谢了。

正则表达式定义了正则语言 单独地,这仅表示某些输入的结构。 在此输入上执行操作需要某种处理工具。 您没有指定要使用的工具,所以我选择了。

多行sed

您写道,“您曾经使用过单行搜索替换功能,但没有使用多行模式。” 也许您是指用sed替代。 请参阅如何使用sed替换多行字符串? 它比单行更复杂,但是有可能。

AWK脚本

AWK以其强大的单行代码而闻名,但是您也可以编写脚本。 这是一个脚本,该脚本使用正则表达式匹配第一个数字来标识新记录/模式的开头。 (我不愿意将其称为“记录”,因为在AWK中它具有特定含义。)它存储前两行的字段,直到遇到第三行。 在第三行,它包含进行所需替换所需的所有信息。 然后打印修改后的前两行并继续。 第三行打印不变(您未指定第三行的替代品)。 如果在下一个记录/模式开始之前还有其他行,则它们也将不变地打印。

目前尚不清楚样本字符在示例输入中的确切位置,因为提交系统已将其替换为空格。 我假设FROM CLIP NAME:和以下字段之间有一个选项卡,并且第一行和第三行上的“变量”也以选项卡分隔。 如果每个记录/模式的第一个数字是十六进制而不是十进制,请将[[:digit:]]替换为[[:xdigit:]]

fixit.awk

#!/usr/bin/awk -f

BEGIN { FS="\t"; n=0 }
{n++}
/^[[:digit:]]+\t/ { n=1 }

# Split and save first two lines
n==1 { line1_NF = split($0, line1, FS); next }
n==2 { line2_NF = split($0, line2, FS); next }
n==3 {
    # At the third line, make replacements
    line1_2 = line1[2]
    line1[2] = $4
    line2[2] = line1_2

    # Print modified first two lines
    printf "%s", line1[1]
    for ( i=2; i<=line1_NF; ++i )
        printf "\t%s", line1[i]
    print ""
    printf "%s", line2[1]
    for ( i=2; i<=line2_NF; ++i )
        printf "\t%s", line2[i]
    print ""
}
1  # Print lines after the second unchanged

你可以像这样使用它

$ awk -f fixit.awk infile.txt

或用管道输送

$ cat infile.txt | awk -f fixit.awk

这不是最受正则表达式启发的解决方案,但它应该可以替代您想要的东西。 对于更复杂的输入结构,理想的解决方案是编写能够正确解释完整输入语言的扫描器和解析器。 使用诸如字符串替换之类的工具可能适用于简单的特定情况,但是您可能会有些细微的差别和假设,这些通常并不适用。 解析器也可以更强大,并且可以实现可以表达用正则表达式无法识别的语言的语法。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM