如何使正则表达式与 perl 命令一起使用并从文件中提取数字?

Posted

技术标签:

【中文标题】如何使正则表达式与 perl 命令一起使用并从文件中提取数字?【英文标题】:How to make regex works with perl command and extract numbers from a file? 【发布时间】:2021-12-29 06:17:36 【问题描述】:

我正在尝试从制表符分隔文件中提取我需要存储在变量中的数字。我正在使用一个正则表达式来解决这个问题,这要归功于我能够构建的一些在线研究。

文件组成如下:

0   0   2500    5000
1   5000    7500    10000
2   10000   12500   15000
3   15000   17500   20000
4   20000   22500   25000
5   25000   27500   30000

给定第一列的数字,我需要提取第二列中的数字。我在网上编写并测试了正则表达式:

(?<=5\t).*?(?=\t)

我需要第六行的 25000。

我开始使用 sed,但您已经知道,即使使用 -E 选项来启用正则表达式的扩展版本,它也不喜欢后向和前向模式。我也尝试了 awkgrep 并且由于类似的原因失败了。

更进一步,我发现 perl 可能是正确的命令,但我无法使其正常工作。我正在尝试使用命令

perl -pe '/(?<=5\t).*?(?=\t)/' | INFO.out

但我承认我知识贫乏,我有点迷茫。

下一步是从变量中读取正则表达式中的“5”,所以如果您已经知道可能出现的问题,请告诉我。

【问题讨论】:

我打赌你只需要n=5; awk -v n="$n" '$1 == nprint $2' file.txt &gt; INFO.out,见demo。 你所拥有的是一个 perl 布尔表达式并且没有操作(也没有分组),这是一种方法:perl -nE '/(?&lt;=5\t)(.*?)(?=\t)/ &amp;&amp; say $1' 顺便说一句。如果您的 grep 支持 -P 标志,您可以这样做:grep -Po '(?&lt;=5\t).*?(?=\t)' 为什么要关闭?!怎么能“更专注?”投票重新开放。 【参考方案1】:

grep 支持 -P 用于 perl 正则表达式,-o 用于仅匹配,所以这适用于后向:

grep -Po '(?<=5\t)\d+' file

perl -n,显示使用s///e 匹配并打印捕获组:

perl -lne 's/^5\t(\d+)/print $1/e' file

grep -Po 可以很容易地使用 shell 变量:

VAR=5 && grep -Po "(?<=$VAR\t)\d+"

【讨论】:

【参考方案2】:

无需后视——将每一行按空格分开并检查第一个字段是否为5

在 Perl 中有一个方便的命令行选项,-a,每行都为我们拆分,我们得到 @F 带有字段的数组

perl -lanE'say $F[1] if $F[0] == 5' data.txt

请注意,这会以数字方式测试 5 (==)

【讨论】:

【参考方案3】:

使用sed

$ var1=$(sed -n 's/^5[^0-9]*\([^ ]*\).*/\1/p' input_file)
$ echo "$var1"
25000

【讨论】:

【参考方案4】:

为什么需要使用正则表达式?如果您所做的只是查找以 5 开头的行并获取第二列,您可以使用 sedcut,例如:

<infile sed -n '/^5\t/p' | cut -f2

输出:

25000

【讨论】:

【参考方案5】:

一种选择是使用 sed,在字符串的开头匹配 5,在制表符之后捕获组中的数字

sed -En 's/^5\t([[:digit:]]+)\t.*/\1/p' file > INFO.out

文件 INFO.out 包含:

25000

【讨论】:

以上是关于如何使正则表达式与 perl 命令一起使用并从文件中提取数字?的主要内容,如果未能解决你的问题,请参考以下文章

Perl正则表达式(regex)在我设为可选时失败

Perl 正则表达式替换,环境变量评估

Perl语言中的正则表达式及其使用

Perl 语法 - 高级特性

将 Perl 与 xm_perl 模块一起使用时出错

Perl 正则表达式 |如何从文件中排除单词