如果两个相似模式之间的特定模式不匹配,则删除两个相似模式之间的所有行

如果两个相似模式之间的特定模式不匹配,则删除两个相似模式之间的所有行

标题应该是:Remove all lines between two similar patterns, including the line of the starting pattern. if another specific pattern in between is not matched。我把它写得更短,因为它对于其他在谷歌上搜索答案的人来说更容易阅读。

关于问题:我有一个特定计算机的可上市股票和不可上市股票的列表。我想创建一个包含可列出共享的所有计算机的列表,并删除其不可读的共享。但我遇到了两个问题。首先,正确删除两个相似图案之间的所有线条。其次,如果发现特定模式,如何不删除两个相似单词之间的行。

我的意见是

Shares for DED-SHD-ED-5:
    [--- Unreadable Shares ---]
        ADMIN$
        C$
        E$
        H$
        IPC$

Shares for DED-SHD-ED-6:
    [--- Unreadable Shares ---]
        ADMIN$
        C$
        IPC$
    [--- Listable Shares ---]
        print$
Shares for DED-SHD-ED-7:
    [--- Unreadable Shares ---]
        ADMIN$
        C$
        IPC$
    [--- Listable Shares ---]
        backup      backup2
Shares for DED-SHD-ED-8:
    [--- Unreadable Shares ---]
        ADMIN$
        C$
        IPC$

Shares for DED-SHD-ED-9:
    [--- Unreadable Shares ---]
        ADMIN$
        C$
        IPC$
        VBRCatalog
    [--- Listable Shares ---]
        backup      backup2

我设法使用以下命令删除所有不可读的共享awk '/Listable Shares/,/Shares for/' input.txt,该命令的问题是DED-SHD-ED-8没有Listable Shares。它会剥离下面的计算机,我将看到atDED-SHD-ED-9的可上市股票DED-SHD-ED-9DED-SHD-ED-8

请参阅下面的输出(我知道列表中第一台计算机的名称丢失,但这对我来说不是问题)

    [--- Listable Shares ---]
        print$
Shares for DED-SHD-ED-7:
    [--- Listable Shares ---]
        backup      backup2
Shares for DED-SHD-ED-8:
    [--- Listable Shares ---]
        backup      backup2

为了解决这个问题,我的想法是在运行之前剥离所有没有可列表共享的计算机awk '/Listable Shares/,/Shares for/' input.txt。起初,我尝试删除“Shares for”和“Shares for”之间的所有行。我在论坛上环顾四周,试图做出更简单的答案,并避免使用复杂的答案,因为它们目前超出了我的理解范围。例如,我使用了这个命令sed '/^Shares for/,/^Shares for/{//!d;};' input.txtsed '/Shares for/,/:/{//!d;};' input2.txt在这里它删除了计算机之间的一半线路。

输出

Shares for DED-SHD-ED-5:
Shares for DED-SHD-ED-6:
    [--- Unreadable Shares ---]
        ADMIN$
        C$
        IPC$
    [--- Listable Shares ---]
        print$
Shares for DED-SHD-ED-7:
Shares for DED-SHD-ED-8:
    [--- Unreadable Shares ---]
        ADMIN$
        C$
        IPC$

为什么它只删除一半计算机的数据?我不明白为什么

我的下一个想法是在命令中添加排除,如果模式Listable在这些行中匹配,则不删除“Shares for”和“Shares for”之间的行。然后删除没有数据的计算机,如DED-SHD-ED-5DED-SHD-ED-7。但也许这不是最好的方法。也许最好删除第一个模式的行,因为看不到模式“Listable”。

我希望得到一些帮助和见解,如何正确处理这一切。

预期输出:

Shares for DED-SHD-ED-6:
    [--- Unreadable Shares ---]
        ADMIN$
        C$
        IPC$
    [--- Listable Shares ---]
        print$
Shares for DED-SHD-ED-7:
    [--- Unreadable Shares ---]
        ADMIN$
        C$
        IPC$
    [--- Listable Shares ---]
        backup      backup2
Shares for DED-SHD-ED-9:
    [--- Unreadable Shares ---]
        ADMIN$
        C$
        IPC$
        VBRCatalog
    [--- Listable Shares ---]
        backup      backup2

答案1

这对你有用吗? shares是我为您的示例输入选择的文件名。

sed -e 'tD' -e '$!N;/.\nShares/s/\n/&&/;:D' -e 'P;D' shares | awk 'BEGIN{RS="\n\n";FS="\n"}/Listable/'
Shares for DED-SHD-ED-6:
    [--- Unreadable Shares ---]
        ADMIN$
        C$
        IPC$
    [--- Listable Shares ---]
        print$
Shares for DED-SHD-ED-7:
    [--- Unreadable Shares ---]
        ADMIN$
        C$
        IPC$
    [--- Listable Shares ---]
        backup      backup2
Shares for DED-SHD-ED-9:
    [--- Unreadable Shares ---]
        ADMIN$
        C$
        IPC$
        VBRCatalog
    [--- Listable Shares ---]
        backup      backup2

如果还没有换行符,基本上sed会在之前插入换行符Shares- 这样我们就可以使用换行符RS="\n\n"作为awk.那么问题就很简单了:只打印包含该词的记录Listable

答案2

理解:

  • Shares如果该块包含字符串,则打印该块Listable Shares

一旦您加入awk其中,通常就可以消除对sed.

一个(详细的)awk想法:

$ cat shares.awk

NF == 0           { next }                        # skip blank lines
$1 == "Shares"    { if (print_block)              # if 1st field is "Shares"; if flag is set (==1) then ...
                       print block                # print the previous block
                    print_block = 0               # clear the flag
                    block = $0                    # initialize a new block
                    next                          # skip to next input line
                  }
/Listable Shares/ { print_block = 1 }             # if line contains "Listable Shares" then set flag
                  { block = block ORS $0 }        # append current line to end of block
END               { if (print_block)              # flush last block to stdout?
                       print block
                  }

进行试驾:

$ awk -f shares.awk input.txt
Shares for DED-SHD-ED-6:
    [--- Unreadable Shares ---]
        ADMIN$
        C$
        IPC$
    [--- Listable Shares ---]
        print$
Shares for DED-SHD-ED-7:
    [--- Unreadable Shares ---]
        ADMIN$
        C$
        IPC$
    [--- Listable Shares ---]
        backup      backup2
Shares for DED-SHD-ED-9:
    [--- Unreadable Shares ---]
        ADMIN$
        C$
        IPC$
        VBRCatalog
    [--- Listable Shares ---]
        backup      backup2

答案3

使用(以前称为 Perl_6)

~$ raku -e '.put for slurp.comb(/^^Shares .*? <?before ^^Shares | $ >/).grep(/Listable/);'   file 

#OR:

~$ raku -e '.put for lines.join("\n").comb(/^^Shares .*? <?before ^^Shares | $ >/).grep(/Listable/);'   file

Raku 是 Perl 家族的一种编程语言。在一个可能被认为是split正则表达式模式上破坏性设置的相反操作中,Raku 提供了comb允许您选择您选择的元素的例程。上面,通过.comb(/^^Shares .*? <?before ^^Shares | $ >/)选择具有以下内容的记录将输入文件分为多个记录:

  • ^^Shares行首文本“共享”,
  • .*?非贪婪任意数量的字符,
  • <?before ^^Shares | $ >正向前瞻,表示在看到?before下一个^^Shares记录模式时或$在文件本身的末尾之前/末尾停止该模式。

在链中的第二个操作中,grep用于仅返回那些包含Listable块的记录。

输入示例:

Shares for DED-SHD-ED-5:
    [--- Unreadable Shares ---]
        ADMIN$
        C$
        E$
        H$
        IPC$

Shares for DED-SHD-ED-6:
    [--- Unreadable Shares ---]
        ADMIN$
        C$
        IPC$
    [--- Listable Shares ---]
        print$
Shares for DED-SHD-ED-7:
    [--- Unreadable Shares ---]
        ADMIN$
        C$
        IPC$
    [--- Listable Shares ---]
        backup      backup2
Shares for DED-SHD-ED-8:
    [--- Unreadable Shares ---]
        ADMIN$
        C$
        IPC$

Shares for DED-SHD-ED-9:
    [--- Unreadable Shares ---]
        ADMIN$
        C$
        IPC$
        VBRCatalog
    [--- Listable Shares ---]
        backup      backup2

示例输出:

Shares for DED-SHD-ED-6:
    [--- Unreadable Shares ---]
        ADMIN$
        C$
        IPC$
    [--- Listable Shares ---]
        print$

Shares for DED-SHD-ED-7:
    [--- Unreadable Shares ---]
        ADMIN$
        C$
        IPC$
    [--- Listable Shares ---]
        backup      backup2

Shares for DED-SHD-ED-9:
    [--- Unreadable Shares ---]
        ADMIN$
        C$
        IPC$
        VBRCatalog
    [--- Listable Shares ---]
        backup      backup2

注意:查看语言内部如何表示数据通常很有启发性,因此这里是输出 combing 到单独的记录中,但是 grepping 所需的块:

~$ raku -e '.raku.put for slurp.comb(/^^Shares .*? <?before ^^Shares | $ >/);'   file
"Shares for DED-SHD-ED-5:\n    [--- Unreadable Shares ---]\n        ADMIN\$\n        C\$\n        E\$\n        H\$\n        IPC\$\n\n"
"Shares for DED-SHD-ED-6:\n    [--- Unreadable Shares ---]\n        ADMIN\$\n        C\$\n        IPC\$\n    [--- Listable Shares ---]\n        print\$\n"
"Shares for DED-SHD-ED-7:\n    [--- Unreadable Shares ---]\n        ADMIN\$\n        C\$\n        IPC\$\n    [--- Listable Shares ---]\n        backup      backup2\n"
"Shares for DED-SHD-ED-8:\n    [--- Unreadable Shares ---]\n        ADMIN\$\n        C\$\n        IPC\$\n\n"
"Shares for DED-SHD-ED-9:\n    [--- Unreadable Shares ---]\n        ADMIN\$\n        C\$\n        IPC\$\n        VBRCatalog\n    [--- Listable Shares ---]\n        backup      backup2\n\n"

https://docs.raku.org/language/operators#Operators
https://docs.raku.org/routine/comb
https://docs.raku.org/routine/grep
https://raku.org

相关内容