【问题标题】:How to delete the matching line and the previous two lines in shell?如何删除shell中匹配的行和前两行?
【发布时间】:2021-03-21 19:26:44
【问题描述】:

我有一个类似下面的文件。

first line
second line
third line
fourth line
fifth line

如何使用 shell 命令删除匹配的行和前 2 行?比如我要匹配第四行,删除第四、三、二行。我知道了我可以使用sed -i '/second/q' filename删除匹配行之后的行,但是如何实现删除宝贵的行?

【问题讨论】:

  • 能否请您以代码形式添加您的努力,这是在 SO 上强烈鼓励的。

标签: shell awk


【解决方案1】:

您能否尝试在 GNU awk 中使用所示示例进行跟踪、编写和测试。将$0=="fourth line" 更改为要在该特定行中匹配的字符串。

tac Input_file | 
awk -v line="4" -v skipLines="2" -v totLines=$(wc -l < Input_file) '
FNR==(totLines-line+1) && $0=="fourth line"{
  ++count
  next
}
count && count++<=skipLines{ next }
1
' | tac

说明:为上述添加详细说明。

tac Input_file |                     ##Using tac command to print contents from bottom to top.
awk -v line="4" -v skipLines="2" -v totLines=$(wc -l < Input_file) '
##passed tac output to awk program which has 3 variables in it.
##line is on which line you want to match for pattern, skipLines(how many lines you want to skip), totLines has total lines in Input_file
FNR==(totLines-line+1) && $0=="fourth line"{
##Checking if current line is which we are looking for and its same as needed pattern.
  ++count                            ##Increasing count with 1 here.
  next                               ##next will skip all statements from here.
}
count && count++<=skipLines{ next }  ##Checking if count is NOT NULL and count is <= skipLines, when both are TRUE do next to skip lines.
1                                    ##1 will print the current line.
' | tac                              ##Sending awk output to tac to get it in its actual order.

注意:请确保在任何有 Input_file 的地方都可以放置您的实际文件名。

【讨论】:

  • 感谢您的详细解决方案。我已经尝试过您的解决方案,但它似乎不起作用。我不确定我犯了什么错误,但我只是复制你的命令句并修改文件名。可以开张支票吗?
【解决方案2】:

仅 awk 版本:

$ awk -v p=3
{
    b[FNR%(p+1)]=$0                 # p+1 sized modulo implemented circular buffer b
    if(((FNR+1)%(p+1)) in b)        # print the one to be overwritten next
        print b[(FNR+1)%(p+1)]      # ... if it exist
}
/fourth line/ {                     # when match met
    delete b                        # reset time for b
}
END {                               # in the end
    for(i=1;i<=(p+1);i++)           # we flush all the values left in buffer
        if(((FNR+i)%(p+1)) in b)
            print b[(FNR+i)%(p+1)]
}

输出:

first line
fifth line

【讨论】:

    猜你喜欢
    • 2018-09-13
    • 1970-01-01
    • 2021-03-13
    • 2014-04-28
    • 1970-01-01
    • 2021-01-26
    • 1970-01-01
    • 1970-01-01
    • 2014-11-15
    相关资源
    最近更新 更多