使用 grep/awk 查找/打印文本文件中的特定值

使用 grep/awk 查找/打印文本文件中的特定值

假设我有一个包含以下 5 行的文本文件:

Tue 18 2022 car model: Toyota , car motor: 2001 , car color: blue , year of production: 2018
Thu 19 2022 car model: Mercedes , car color: black , year of production: 2012 , car motor: 4000
Thu 20 2022 used: yes , car motor: 1999 , car model: Mercedes , car color: black , year of production: 2012
Thu 20 2022 car model: Kia , car motor: 1500 , car color: red , used: no , year of production: 2010
Thu 20 2022 price: 150, car model: GMC  , car color: purple , car motor: 3500 , year of production: 2010

我正在寻找 grep/awk (或 freebsd 11 上可用的其他实用程序),它将查找/打印以下条件评估为 TRUE 的每一行:

Phrase "car motor:" followed by a space and then a numerical value greater than 2000

这样的 grep/awk 预计会从文本文件中找到/打印以下行:

Tue 18 2022 car model: Toyota , car motor: 2001 , car color: blue , year of production: 2018
Thu 19 2022 car model: Mercedes , car color: black , year of production: 2012 , car motor: 4000
Thu 20 2022 price: 150, car model: GMC  , car color: purple , car motor: 3500 , year of production: 2010

答案1

我认为 perl 将在 freebsd 上可用,并且您的要求可以直接转换:

perl -ne 'print if /car motor: (\d+)/ and $1 > 2000' file

答案2

使用 GNU awk 将第三个参数匹配到 match():

$ awk 'match($0,/car motor: ([0-9]+)/,a) && (a[1] > 2000)' file
Tue 18 2022 car model: Toyota , car motor: 2001 , car color: blue , year of production: 2018
Thu 19 2022 car model: Mercedes , car color: black , year of production: 2012 , car motor: 4000
Thu 20 2022 price: 150, car model: GMC  , car color: purple , car motor: 3500 , year of production: 2010

或使用任何 awk:

$ awk 'match($0,/car motor: [0-9]+/) && (substr($0,RSTART+11) > 2000)' file
Tue 18 2022 car model: Toyota , car motor: 2001 , car color: blue , year of production: 2018
Thu 19 2022 car model: Mercedes , car color: black , year of production: 2012 , car motor: 4000
Thu 20 2022 price: 150, car model: GMC  , car color: purple , car motor: 3500 , year of production: 2010

或者也可以使用任何 awk,但更神秘一点:

$ awk '{k=$0} sub(/.*car motor: /,"",k) && (k > 2000)' file
Tue 18 2022 car model: Toyota , car motor: 2001 , car color: blue , year of production: 2018
Thu 19 2022 car model: Mercedes , car color: black , year of production: 2012 , car motor: 4000
Thu 20 2022 price: 150, car model: GMC  , car color: purple , car motor: 3500 , year of production: 2010

答案3

我们需要许多组合来排除2000自身,我们将其视为字符串而不是数值:

grep -E 'car motor: (200[1-9]|20[1-9][0-9]|2[1-9][0-9]{2}|[3-9][0-9]{3}|[1-9][0-9]{4,})' yourfile

答案4

使用(以前称为 Perl_6)

raku -ne '.put if m/car \s motor \: \s (\d**4..*)/ && $0 > 2000;' 

或者

raku -ne '.put if .grep(/car \s motor \: \s (\d**4..*)/ && {$0 > 2000});' 

示例输入(感谢@schrodigerscatcuriosity):

Tue 18 2022 car model: Toyota , car motor: 2001 , car color: blue , year of production: 2018
Thu 19 2022 car model: Mercedes , car color: black , year of production: 2012 , car motor: 4000
Thu 20 2022 used: yes , car motor: 1999 , car model: Mercedes , car color: black , year of production: 2012
Thu 20 2022 car model: Kia , car motor: 1500 , car color: red , used: no , year of production: 2010
Thu 20 2022 price: 150, car model: GMC  , car color: purple , car motor: 3500 , year of production: 2010

car motor: 1
car motor: 100
car motor: 1000
car motor: 2000
car motor: 2001
car motor: 4000
car motor: 9999
car motor: 10000

示例输出(使用上面的任一代码示例):

Tue 18 2022 car model: Toyota , car motor: 2001 , car color: blue , year of production: 2018
Thu 19 2022 car model: Mercedes , car color: black , year of production: 2012 , car motor: 4000
Thu 20 2022 price: 150, car model: GMC  , car color: purple , car motor: 3500 , year of production: 2010
car motor: 2001
car motor: 4000
car motor: 9999
car motor: 10000

看起来好像适用于 FreeBSD,前提是您按照以下建议安装 Rakudo 编译器(来自源代码):

https://rakudo.org/downloads/rakudo/source
https://fluca1978.github.io/2020/01/14/RakuOnFreeBSD.html

它甚至看起来好像 Rakudo-Star 二进制文件(Rakudo 加上核心模块)现在/曾经可用于 FreeBSD:

https://www.tyil.nl/post/2020/06/21/lately-in-raku/

简而言之,使用 Raku 匹配运算符的第一个示例m/.../几乎是 @glenn_jackman 的 Perl 代码的直接翻译。为了减少“反斜杠”体验,可以这样写:

raku -ne '.put if m[ "car motor: " (\d**4..*) ] && $0 > 2000;'   

第二个示例使用 Rakugrep运算符。有时,最好返回匹配的行并将不匹配的行留空。您可以在 Raku 中执行此操作,grep如下所示(对所有行进行编号):

raku -ne 'put(++$, ". ", .grep: / "car motor: " (\d**4..*)/ && {$0 > 2000} );' 

示例输出:

1. Tue 18 2022 car model: Toyota , car motor: 2001 , car color: blue , year of production: 2018
2. Thu 19 2022 car model: Mercedes , car color: black , year of production: 2012 , car motor: 4000
3. 
4. 
5. Thu 20 2022 price: 150, car model: GMC  , car color: purple , car motor: 3500 , year of production: 2010
6. 
7. 
8. 
9. 
10. 
11. car motor: 2001
12. car motor: 4000
13. car motor: 9999
14. car motor: 10000

https://raku.org

相关内容