如何删除两条线之间的单线

如何删除两条线之间的单线

我的文件中有数百万条记录,如下所示

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

答案1

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

答案2

紧凑型解决方案sed

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

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

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

答案3

凭借基本的awk...

版本 1 只会删除grepOP 描述之后的行:

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行以及前面的非 grep 行,该行遵循 OP 的示例输出:

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

答案4

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

相关内容