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 / 问题 / 496773
Accepted
k-a-v
k-a-v
Asked: 2019-01-26 14:56:07 +0800 CST2019-01-26 14:56:07 +0800 CST 2019-01-26 14:56:07 +0800 CST

计算文件中的多行模式

  • 772

我正在寻找一种在文件中搜索多行模式的方法。

例如,假设这个数字列表是我的输入文件:

3
2
5
4
8
2
5
4
2
4
2
5
4

如果我想搜索第 2-4 行(包括)的实例,我希望结果是:

3

因为那是那些特定行被精确重复的次数。我还希望它适用于任何给定数量的行,以及文件中任何给定的行号范围。

bash text-processing
  • 5 5 个回答
  • 966 Views

5 个回答

  • Voted
  1. Best Answer
    Sparhawk
    2019-01-26T16:05:25+08:002019-01-26T16:05:25+08:00

    您可以使用pcregrep,它在大多数发行版中都可用。以下命令匹配固定字符串。

    pcregrep -Mc '^2\n5\n4$' input.txt
    

    解释

    从手册页看,pcgrep 是“一个与 Perl 兼容的正则表达式的 grep”。

    • -M: 匹配多行的正则表达式
    • -c:输出匹配的数量(计数),而不是匹配本身
    • ^2\n5\n4$: 2, 5, 4 的正则表达式,每个在单独的行上。

    取而代之的是特定线条的图案

    问题中的后续评论表明要匹配的模式不是固定字符串,而是一般的“第 2 到 4 行”。在这里,您可以使用命令替换来解析输入文件中的行。

    pcregrep -Mc "^\Q$(sed -n 2,4p input.txt)\E$" input.txt
    

    解释

    • tail -n+2 input.txt: 输出文件,从第 2 行开始
    • head -n3: 只输出前三行
    • \Q...\E:引用基本字符串匹配的...部分,而不是正则表达式匹配(假设命令的输出不包含\E)。

    请注意,它假定 的输出的最后几行sed ... input.txt不为空,因为命令替换 ( $(...)) 会去除所有尾随换行符。

    • 2
  2. Rakesh Sharma
    2019-01-27T03:34:20+08:002019-01-27T03:34:20+08:00
    $ perl -l -0777pe '$_=()=/^2\n5\n4$/mg' input_file
    3
    

    在职的:

    • -0777=> slurp 模式,意思是读入整个文件。
    • -p => 在读取下一条记录之前,将当前记录打印$_到标准输出。
    • -l => 设置 RS = ORS = "\n"
    • 正则表达式/^2\n5\n4$/mg隐式应用于$_,在我们的例子中是整个文件记住。/m除了字符串开头和字符串结尾之外,正则表达式修饰符也应匹配行结尾和开头。/g修饰符将获得$_又名整个文件中的所有匹配项。
    • 我们在列表上下文中执行此操作,并将其分配给一个空列表。$_ 因此被重新分配了列表中元素的数量,这是正则表达式真正匹配的次数。

    高温高压

    • 1
  3. Jim L.
    2019-01-26T15:30:11+08:002019-01-26T15:30:11+08:00

    您的帖子没有提到对正则表达式支持的任何要求,因此我假设您将搜索固定的文字文本字符串。

    这可能不是你见过的最快的算法,但如果你有足够的时间,它会起作用。它有一个小缺陷,如果有多个 N 行模式以相同的第一行开头并且具有相同的 SHA256 哈希,则会给出不正确的结果。它假定所有可能的 N 行模式都具有唯一的 SHA256 哈希值。

    在大文件上运行速度会非常缓慢,尤其是那些包含多次出现模式第一行的文件。

    #!/usr/bin/env bash
    
    # What's the name of the list file?
    LIST=list
    
    # What's the name of the pattern file?
    PATTERN=pattern
    
    # We'll figure out how many times the pattern lines appear (consecutively) in the list.
    
    # Where's your SHA256 tool?
    SHA256=/sbin/sha256
    
    # what's the first line of pattern?
    PATTERN_START="$(head -1 $PATTERN)"
    
    # where in the list does that single line appear (what line numbers?)
    START_LINES="$(grep -nx "$PATTERN_START" $LIST | sed -e 's/:.*//')"
    
    # how many lines long is the pattern?
    PAT_LEN="$(grep -c  ^ < $PATTERN)"
    
    echo Pattern is $PAT_LEN lines long, and might start at any of these lines:
    echo $START_LINES
    
    PAT_HASH="$($SHA256 < "$PATTERN")"
    
    # So how many times does $PATTERN appear consecutively in $LIST?
    PAT_COUNT=0
    
    for LINE in $START_LINES
    do
            HASH="$(tail +$LINE $LIST | head -$PAT_LEN | $SHA256 -q)"
            if [ "$HASH" = "$PAT_HASH" ]
            then
                    echo match at line $LINE
                    PAT_COUNT=$(($PAT_COUNT+1))
            fi
    done
    
    echo The pattern was found $PAT_COUNT times
    

    输出:

    $ cat list
    3
    2
    5
    4
    8
    2
    5
    4
    2
    4
    2
    5
    4
    $ cat pattern
    2
    5
    4
    $ . foo.sh 
    Pattern is 3 lines long, and might start at any of these lines:
    2 6 9 11
    match at line 2
    match at line 6
    match at line 11
    The pattern was found 3 times
    
    • 0
  4. Niko Gambt
    2019-01-26T18:21:51+08:002019-01-26T18:21:51+08:00
    mpc() {
        # mpc: multiline-pattern counter
        # the first argument $1 is the first line number to include in the pattern
        # the second argument $2 is the last line number to include in the pattern
        # the third argument $3 is the input file
    
        line_count=$(( $2 - $1 + 1 ))
        multiline_pattern=$(head -n $2 "$3"| tail -n $line_count)
        awk -v RS='' -v FPAT="$multiline_pattern" '{print NF}' "$3"
    }
    
    # count how many times multiline-pattern defined by lines 2 to 4 (inclusive) occurs
    mpc 2 4 input_file
    

    要求:

    第二个参数必须至少等于或大于第一个参数。如果您违反此规定,我不保证输出。

    免责声明:

    \如果字符和/或$出现在作为模式包含的任何行中,这将不起作用。awk即使它们被反斜杠转义,也很难将这些字符作为模式的一部分来处理。

    • 0
  5. bu5hman
    2019-01-27T06:55:09+08:002019-01-27T06:55:09+08:00

    怎么样

    a="2 5 4"; tr '\n' ' '  < test | grep -o "[^0-9]$a[^0-9]" | wc -l
    

    使用您选择的分隔符......

    22 5 44您需要正则表达式来防止在 .... ... 或类似情况下匹配

    • 0

相关问题

  • 从文本文件传递变量的奇怪问题

  • 虽然行读取保持转义空间?

  • `tee` 和 `bash` 进程替换顺序

  • 运行一个非常慢的脚本直到它成功

  • 如何更改字符大小写(从小到大,反之亦然)?同时[重复]

Sidebar

Stats

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

    模块 i915 可能缺少固件 /lib/firmware/i915/*

    • 3 个回答
  • Marko Smith

    无法获取 jessie backports 存储库

    • 4 个回答
  • Marko Smith

    如何将 GPG 私钥和公钥导出到文件

    • 4 个回答
  • Marko Smith

    我们如何运行存储在变量中的命令?

    • 5 个回答
  • Marko Smith

    如何配置 systemd-resolved 和 systemd-networkd 以使用本地 DNS 服务器来解析本地域和远程 DNS 服务器来解析远程域?

    • 3 个回答
  • Marko Smith

    dist-upgrade 后 Kali Linux 中的 apt-get update 错误 [重复]

    • 2 个回答
  • Marko Smith

    如何从 systemctl 服务日志中查看最新的 x 行

    • 5 个回答
  • Marko Smith

    Nano - 跳转到文件末尾

    • 8 个回答
  • Marko Smith

    grub 错误:你需要先加载内核

    • 4 个回答
  • Marko Smith

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

    • 7 个回答
  • Martin Hope
    user12345 无法获取 jessie backports 存储库 2019-03-27 04:39:28 +0800 CST
  • Martin Hope
    Carl 为什么大多数 systemd 示例都包含 WantedBy=multi-user.target? 2019-03-15 11:49:25 +0800 CST
  • Martin Hope
    rocky 如何将 GPG 私钥和公钥导出到文件 2018-11-16 05:36:15 +0800 CST
  • Martin Hope
    Evan Carroll systemctl 状态显示:“状态:降级” 2018-06-03 18:48:17 +0800 CST
  • Martin Hope
    Tim 我们如何运行存储在变量中的命令? 2018-05-21 04:46:29 +0800 CST
  • Martin Hope
    Ankur S 为什么 /dev/null 是一个文件?为什么它的功能不作为一个简单的程序来实现? 2018-04-17 07:28:04 +0800 CST
  • Martin Hope
    user3191334 如何从 systemctl 服务日志中查看最新的 x 行 2018-02-07 00:14:16 +0800 CST
  • Martin Hope
    Marko Pacak Nano - 跳转到文件末尾 2018-02-01 01:53:03 +0800 CST
  • Martin Hope
    Kidburla 为什么真假这么大? 2018-01-26 12:14:47 +0800 CST
  • Martin Hope
    Christos Baziotis 在一个巨大的(70GB)、一行、文本文件中替换字符串 2017-12-30 06:58:33 +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