使用 grep 和 sed 在 shell 中查找和替换同一文件中的多行

Posted

技术标签:

【中文标题】使用 grep 和 sed 在 shell 中查找和替换同一文件中的多行【英文标题】:To find and replace multiple lines in the same file in shell using grep and sed 【发布时间】:2021-09-30 12:48:00 【问题描述】:

grep -A 4 -B 3 "ABCD" file.txt | sed -i.bak 's/^/#/g'

我正在使用上面的代码插入带有# 的搜索模式的第一行。 我需要根据一种搜索模式替换多行。 这些内容必须在同一文件中替换(替换),否则新文件也应包含原始内容。

以下是输入文件的预期输出示例。

假设file.txt的内容是-

PQRS
1
2
3
4
ABCD
1
2
3
4
WXYZ
1
2
3
4
ABCD
1
2
3
4

预期输出是 -

PQRS
1
#2
#3
#4
#ABCD
#1
#2
#3
#4
WXYZ
1
#2
#3
#4
#ABCD
#1
#2
#3
#4

这里有任何想法。 有没有一种巧妙的方法可以做到这一点,而不是使用 perl 或任何其他脚本循环和移动文件指针。

【问题讨论】:

只是为了确保我理解,您想在模式前的 3 行、模式之后的 4 行和模式线本身前面加上 # 【参考方案1】:

这可能对你有用(GNU sed):

sed -E ':a;N;s/\n/&/7;Ta;/(.*\n)3ABCD(.*\n)4/s/^[^#]/#&/mg;P;D' file

收集 7 行,如果第四行以 ABCD 开头,则在 7 行中的每一行之前插入 #(除非它已经被注释)。

使用 grep 的替代方法:

grep -n -A4 -B3 'ABCD' file | 
sed -nE 's/^([0-9]+).*/\1s@^[^#]@#\&@/p' | sed -f - file

【讨论】:

【参考方案2】:

这是一个内联的 sed 方法:

#!/usr/bin/env bash

pattern=$1:-ABCD
input=$2:-file.txt

sed "
/^[[:upper:]]*$/ 
    /$pattern/   # if target pattern, append the next line and comment both
        N
        s/^/#/
        s/\n/\n#/
    


/^[[:digit:]]*$/   # if digit(s), comment out if it's not a 1
    /^1$/! 
        s/^/#/
    

" $input

【讨论】:

以上是关于使用 grep 和 sed 在 shell 中查找和替换同一文件中的多行的主要内容,如果未能解决你的问题,请参考以下文章

Shell脚本 正则表达式 grep sed awk 工具

shell脚本应用正则表达式grep,sed,awk,的应用

shell脚本应用正则表达式grep,sed,awk,的应用

Shell编程之正则表达式(sed)

shell的查找与替换

shell脚本之正则表达式