AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / unix / 问题 / 406507
Accepted
geet
geet
Asked: 2017-11-24 00:58:02 +0800 CST2017-11-24 00:58:02 +0800 CST 2017-11-24 00:58:02 +0800 CST

如何删除两行之间的单行

  • 772

我在一个文件中有数百万条记录,看起来像这样

echo "NEW Cell"
grep "2553,24" out.2A25.20090308.64436.7.HDF.txt.text = 22.58   5.39  82.09 237
echo "NEW Cell"
grep "2555,20" out.2A25.20090308.64436.7.HDF.txt.text = 24.72   5.58  82.05 237
echo "NEW Cell"
grep "2557,20" out.2A25.20090308.64436.7.HDF.txt.text = 19.75   5.62  82.11 170
grep "2557,21" out.2A25.20090308.64436.7.HDF.txt.text = 24.34   5.58  82.13 120
grep "2558,22" out.2A25.20090308.64436.7.HDF.txt.text = 22.2   5.57  82.19 120
echo "NEW Cell"
grep "2560,22" out.2A25.20090308.64436.7.HDF.txt.text = 24.69   5.62  82.25 160
grep "2561,23" out.2A25.20090308.64436.7.HDF.txt.text = 24.74   5.60  82.30 120
echo "NEW Cell"
grep "2560,24" out.2A25.20090308.64436.7.HDF.txt.text = 19.38   5.54  82.30 170
echo "NEW Cell"

现在我想删除带有“grep”的行,条件是它是包含“New Cell”的行之间的唯一行。也就是说,如果新单元格之间有一行 grep,则应删除该行。

这个怎么做?

我的输出应该是这样的,

echo "NEW Cell"
grep "2557,20" out.2A25.20090308.64436.7.HDF.txt.text = 19.75   5.62  82.11 170
grep "2557,21" out.2A25.20090308.64436.7.HDF.txt.text = 24.34   5.58  82.13 120
grep "2558,22" out.2A25.20090308.64436.7.HDF.txt.text = 22.2   5.57  82.19 120
echo "NEW Cell"
grep "2560,22" out.2A25.20090308.64436.7.HDF.txt.text = 24.69   5.62  82.25 160
grep "2561,23" out.2A25.20090308.64436.7.HDF.txt.text = 24.74   5.60  82.30 120
awk sed
  • 4 4 个回答
  • 630 Views

4 个回答

  • Voted
  1. Best Answer
    RomanPerekhrest
    2017-11-24T01:31:11+08:002017-11-24T01:31:11+08:00

    AWK解决方案:

    awk 'NR==n{ if (/NEW Cell/) { f=0 } else print r ORS gr }
         /NEW Cell/{ f=1; n=NR+2; r=$0; next }
         f && n-NR==1 && /^grep /{ gr=$0; next }1' file
    
    • /NEW Cell/{ f=1; n=NR+2; r=$0; next }- 在遇到线与NEW Cell

      • f=1= 设置活动标志f=1
      • n=NR+2- 设置n为以下要处理的最大行数(下 2 行)
      • r=$0- 捕获线
      • next- 跳到下一条记录
    • f && n-NR==1 && /^grep /- 遇到以关键字n-NR==1开头的第二行(由 确保)grep

      • gr=$0; next- 捕获grep线并跳转到下一个(第三个)记录
    • NR==n{ if (/NEW Cell/) { f=0 } else print r ORS gr }- 在遇到第三条关键线时(由 保证NR==n)

      • if (/NEW Cell/) { f=0 }- 如果已处理部分下的第 3 行包含NEW Cell- 重置当前处理f=0(跳过所有先前捕获的行)
      • else print r ORS gr- 否则打印所有以前捕获的行

    输出:

    echo "NEW Cell"
    grep "2557,20" out.2A25.20090308.64436.7.HDF.txt.text = 19.75   5.62  82.11 170
    grep "2557,21" out.2A25.20090308.64436.7.HDF.txt.text = 24.34   5.58  82.13 120
    grep "2558,22" out.2A25.20090308.64436.7.HDF.txt.text = 22.2   5.57  82.19 120
    echo "NEW Cell"
    grep "2560,22" out.2A25.20090308.64436.7.HDF.txt.text = 24.69   5.62  82.25 160
    grep "2561,23" out.2A25.20090308.64436.7.HDF.txt.text = 24.74   5.60  82.30 120
    
    • 3
  2. Philippos
    2017-11-24T05:20:57+08:002017-11-24T05:20:57+08:00

    紧凑型解决方案sed:

    sed '/NEW Cell/!{H;d;};x;/\n.*\n/!d'
    

    如果该行不包含NEW Cell执行H将该行附加到保留空间并d停止对该行的处理。

    所以进一步的命令只适用于NEW Cell行:x交换模式空间和保持空间,因此该行现在在保持空间中并且可以附加更多的行,而模式空间包含附加到最后NEW Cell一行的所有内容。您的要求是行之间有不止一行NEW Cell,因此模式空间中必须至少有两个换行符。如果没有,请删除它而不输出:/\n.*\n/!d.

    • 2
  3. B Layer
    2017-11-24T01:36:54+08:002017-11-24T01:36:54+08:00

    用基本awk...

    版本 1 只会删除grep遵循 OP 描述的行:

    awk '/^grep/ { if (f) { if (length(s) > 0) { print s; s="" } print } \
         else { f=1; s=$0 } } ! /^echo/ { print; f=0 } \
         ! /^echo/ && ! /^grep/ { print }' inputfile
    

    版本 2 将删除单独grep的行以及遵循 OP 示例输出的前面的非 grep 行:

    awk '/^grep/ { if (f) { if (length(s) > 0) { print s; s="" } print } \
        else { f=1; s=s "\n" $0 } } /^echo/ { s=$0; f=0 } \
        ! /^echo/ && ! /^grep/ { print }' inputfile
    

    版本 2 的可读形式...

    /^grep/ { 
       if (found) {  # found==true : already encountered first grep line
           if (length(save) > 0) {
              print save
              save=""
           }
           print
       } else {
           found=1
           save=save "\n" $0  # append the first grep line to saved preceding line
       }
    }
    
    /^echo/ { 
        save=$0  # save this line for possible later printing
        found=0
    }
    
    # print anything else
    ! /^echo/ && ! /^grep/ { print }
    

    可以通过将内容放入文件(例如awkfile)和awk -f awkfile inputfile.

    • 1
  4. MiniMax
    2017-11-24T10:50:08+08:002017-11-24T10:50:08+08:00
    gawk '
    /\n.+\n/{
        printf("%s%s", RS, $0);
    }' RS='echo "NEW Cell"\n' input.txt
    

    解释:

    1. RS='echo "NEW Cell"\n'-RS是输入记录分隔符,默认为换行符。现在它被更改为echo "NEW Cell"\n,因此,该字符串的所有出现都将被删除,并且它们之间的所有字符都成为记录项。
    2. /\n.+\n/{- 仅适用于与此模式匹配的记录 - 换行符、一个或多个字符、换行符。所以,它只匹配多行记录,单行记录不匹配,因为它只有一个\n.
    3. printf("%s%s", RS, $0);- 打印以RS( echo "NEW Cell"\n) 开头的记录。

    输出

    echo "NEW Cell"
    grep "2557,20" out.2A25.20090308.64436.7.HDF.txt.text = 19.75   5.62  82.11 170
    grep "2557,21" out.2A25.20090308.64436.7.HDF.txt.text = 24.34   5.58  82.13 120
    grep "2558,22" out.2A25.20090308.64436.7.HDF.txt.text = 22.2   5.57  82.19 120
    echo "NEW Cell"
    grep "2560,22" out.2A25.20090308.64436.7.HDF.txt.text = 24.69   5.62  82.25 160
    grep "2561,23" out.2A25.20090308.64436.7.HDF.txt.text = 24.74   5.60  82.30 120
    
    • 1

相关问题

  • 重新排列字母并比较两个单词

  • 多行文件洗牌

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    JSON数组使用jq来bash变量

    • 4 个回答
  • Marko Smith

    日期可以为 GMT 时区格式化当前时间吗?[复制]

    • 2 个回答
  • Marko Smith

    bash + 通过 bash 脚本从文件中读取变量和值

    • 4 个回答
  • Marko Smith

    如何复制目录并在同一命令中重命名它?

    • 4 个回答
  • Marko Smith

    ssh 连接。X11 连接因身份验证错误而被拒绝

    • 3 个回答
  • Marko Smith

    如何下载软件包而不是使用 apt-get 命令安装它?

    • 7 个回答
  • Marko Smith

    systemctl 命令在 RHEL 6 中不起作用

    • 3 个回答
  • Marko Smith

    rsync 端口 22 和 873 使用

    • 2 个回答
  • Marko Smith

    以 100% 的利用率捕捉 /dev/loop -- 没有可用空间

    • 1 个回答
  • Marko Smith

    jq 打印子对象中所有的键和值

    • 2 个回答
  • Martin Hope
    EHerman JSON数组使用jq来bash变量 2017-12-31 14:50:58 +0800 CST
  • Martin Hope
    Christos Baziotis 在一个巨大的(70GB)、一行、文本文件中替换字符串 2017-12-30 06:58:33 +0800 CST
  • Martin Hope
    Drux 日期可以为 GMT 时区格式化当前时间吗?[复制] 2017-12-26 11:35:07 +0800 CST
  • Martin Hope
    AllisonC 如何复制目录并在同一命令中重命名它? 2017-12-22 05:28:06 +0800 CST
  • Martin Hope
    Steve “root”用户的文件权限如何工作? 2017-12-22 02:46:01 +0800 CST
  • Martin Hope
    Bagas Sanjaya 为什么 Linux 使用 LF 作为换行符? 2017-12-20 05:48:21 +0800 CST
  • Martin Hope
    Cbhihe 将默认编辑器更改为 vim for _ sudo systemctl edit [unit-file] _ 2017-12-03 10:11:38 +0800 CST
  • Martin Hope
    showkey 如何下载软件包而不是使用 apt-get 命令安装它? 2017-12-03 02:15:02 +0800 CST
  • Martin Hope
    youxiao 为什么目录 /home、/usr、/var 等都具有相同的 inode 编号 (2)? 2017-12-02 05:33:41 +0800 CST
  • Martin Hope
    user223600 gpg —list-keys 命令在将私钥导入全新安装后输出 uid [未知] 2017-11-26 18:26:02 +0800 CST

热门标签

linux bash debian shell-script text-processing ubuntu centos shell awk ssh

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve