将一条线与另一条线交换

将一条线与另一条线交换

我有文件

Line 1
Line 2 MATCH
Line 3
Line 4
Line 1
Line 2 MATCH
Line 3
Line 4

我想针对每种情况将行与“MATCH”和“Line 1”交换。我尝试搜索其他问题,但这些问题将匹配的行移动到最后一行,并且我不太了解重新制作我的版本以获得最终输出的代码,例如:

Line 2 MATCH
Line 1
Line 3
Line 4
Line 2 MATCH
Line 1
Line 3
Line 4

答案1

sed与使用N;P;D cycle:

sed -e '$!N;s/\(Line 1\)\(\n\)\(.*MATCH.*\)/\3\2\1/;t' -e 'P;D' infile

仅当 with 行MATCH前面有: 时,这才会交换Line 1t如果成功,则 without 标签分支到脚本末尾,因此如果Line 1后面有连续行 with ,则可以避免再次交换MATCH。调整任何前导/尾随空白的正则表达式。

答案2

如果想法是与前一行交换该MATCH行,那么可以这样做:

$ awk '!/MATCH/ { if (NR > 1) print prev; prev=$0} 
        /MATCH/ {print $0;} 
        END {print prev}' < file
Line 2 MATCH
Line 1
Line 3
Line 4
Line 2 MATCH
Line 1
Line 3
Line 4

该脚本保留 中的前一行prev,在不匹配的行上打印并更新它。在与模式匹配的行上,它打印当前行,将前一行留在变量中以供下一行打印。

NR==1当没有前一行要打印时,以及END当我们打印保留的行时,第一行 ( ) 的特殊情况。

答案3

使用ed

$ printf 'g/MATCH/m-2\n,p\n' | ed -s file
Line 2 MATCH
Line 1
Line 3
Line 4
Line 2 MATCH
Line 1
Line 3
Line 4

m命令将当前行移至后续目标地址。在这里,我们找到所有匹配的行MATCH(正则g表达式前面的 使得这是一个“全局”操作),并且对于每一行将其向上移动一行(到“在该行之后向上两行”)。效果是这些MATCH行与前面的行交换位置。

编辑脚本中的最后部分,p仅显示修改后的编辑缓冲区。这可以更改为wq将更改后的编辑缓冲区写回原始文件之类的内容。

请注意,用于ed编辑文件可能看起来很整洁,但不建议用于大文件,因为整个文件都会读入内存。

答案4

sed "s/第 2 行匹配//g"|sed "s/第 1 行/第 2 行匹配\n&/g"

上面的命令运行良好

相关内容