我有文件
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 1
:t
如果成功,则 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"
上面的命令运行良好