首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Perl或Awk:匹配电影运行时间超过5小时

Perl或Awk:匹配电影运行时间超过5小时
EN

Stack Overflow用户
提问于 2019-04-12 09:19:33
回答 5查看 125关注 0票数 2

我需要重新编目所有运行时间超过5小时的电影。

示例数据:

代码语言:javascript
复制
239835<TAB> 92075<TAB>Moonlighting, seasons one and two<TAB>NVIDEO<TAB>DVD<TAB>6 videodiscs (approximately 1200 min.) :
628328  180001  7th heaven. NVIDEO  DVD 5 videodiscs (15 hr., 57 min.) :
773429  291072  Veronica Mars.  NVIDEO  DVD 6 videodiscs (842 min.) :
789908  379843  Castle in the Sky   NVIDEO  JDVD    2 videodiscs (approximately 125 min.) :
856287  208624  The Munsters.   NVIDEO  DVD 12 videodiscs (approximately 33 hr.) :
1076125 254085  From up on Poppy Hill (Rated PG)    NVIDEO  JDVD    2 videodiscs (91 min.) :
1154016 264851  Columbo.    NVIDEO  DVD 5 videodiscs (725 min.) :
1217001 113980  CSI, crime scene investigation. NVIDEO  DVD 5 videodiscs (approximately 732 min.) :
1227803 280535  Seattle Seahawks    NVIDEO  DVD 3 videodiscs (500 min.) :
1227804 280535  Seattle Seahawks    NVIDEO  DVD 3 videodiscs (500 min.) :
1287497 293511  Seattle Seahawks :  NVIDEO  DVD 3 videodiscs (400 min.) :
1287499 293511  Seattle Seahawks :  NVIDEO  DVD 3 videodiscs (400 min.) :
1367994 228775  Spongebob Squarepants.  NVIDEO  JDVD    4 videodiscs (469 min.) :
1368002 257248  SpongeBob SquarePants.  NVIDEO  JDVD    4 videodiscs (589 min.) :

是否有一个快速的perl或awk代码片段或一行程序:* Print整行if *# of "min“大于300或*# of "hr(s)”大于5

类似于:

代码语言:javascript
复制
perl -F\\t -ane 'print if $F[6] <substring or capture group representing minutes> > 300' file.csv

使用awk拉近距离

代码语言:javascript
复制
awk -F'\t' '$6 ~ /^.*\(.*[3-9][[:digit:]]{2}[[:space:]]+min.*\)/ {print}' minutes.csv

REGEX模式:分钟数大于300:/^.*\(.*[[:space:]][3-9][[:digit:]]{2}[[:space:]]+min.*\)/

大于1000分钟:/^.*\(.*[[:digit:]]{4,}[[:space:]]+min.*\)/

大于5小时:/^.*\(.*[[:space:]][5-9]{1}[[:space:]]+hr.*\)/

大于10小时:/^.*\(.*[[:space:]][[:digit:]]{4}[[:space:]]+hr.*\)/

有没有更简单、更简洁的方法?

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2019-04-12 10:06:44

与其试图用一个庞大的正则表达式来做所有的事情,我认为把它分成几个不同的正则表达式会更具可读性,也更容易理解,当你稍后再来看它的时候。不需要给perl看起来像线路噪声的刻板印象提供支持……

代码语言:javascript
复制
$ perl -F\\t -ane 'print if ($F[5] =~ /(\d+) hr\./ && $1 > 5) || ($F[5] =~ /(\d+) min\./ && $1 > 300)' input.tsv

这将提取第六列中hr.min.之前的数字(如果匹配的字符串也出现在name列中,则仅提取该数字),并对它们进行比较,以查看它们是否分别大于5或300,并且只打印那些匹配的行。

票数 4
EN

Stack Overflow用户

发布于 2019-04-12 09:34:29

您可以将正则表达式与捕获组和perl一起使用:

代码语言:javascript
复制
> perl -ne'/\(.*?(?:(\d+) hr\.)?.*?(?:(\d+) min\.)?.*?\)/&&($1>5||$2>300)&&print' catalog
628328  180001  7th heaven. NVIDEO  DVD 5 videodiscs (15 hr., 57 min.) :
773429  291072  Veronica Mars.  NVIDEO  DVD 6 videodiscs (842 min.) :
1154016 264851  Columbo.    NVIDEO  DVD 5 videodiscs (725 min.) :
1227803 280535  Seattle Seahawks    NVIDEO  DVD 3 videodiscs (500 min.) :
1227804 280535  Seattle Seahawks    NVIDEO  DVD 3 videodiscs (500 min.) :
1287497 293511  Seattle Seahawks :  NVIDEO  DVD 3 videodiscs (400 min.) :
1287499 293511  Seattle Seahawks :  NVIDEO  DVD 3 videodiscs (400 min.) :
1367994 228775  Spongebob Squarepants.  NVIDEO  JDVD    4 videodiscs (469 min.) :
1368002 257248  SpongeBob SquarePants.  NVIDEO  JDVD    4 videodiscs (589 min.) :
票数 2
EN

Stack Overflow用户

发布于 2019-04-12 12:46:28

因为5小时是300分钟,你不需要单独处理它们,只需将任何小时和/或分钟规格转换为分钟即可。使用任何awk:

代码语言:javascript
复制
awk -F'\t' '
    {
        hrs  = ( match($6,/[0-9]+ hr/)  ? substr($6,RSTART)+0 : 0 )
        mins = ( match($6,/[0-9]+ min/) ? substr($6,RSTART)+0 : 0 )
    }
    (hrs*60 + mins) > 300
' file

但是如果你愿意,你可以把它写成两个单独的测试:

代码语言:javascript
复制
awk -F'\t' '
    {
        hrs  = ( match($6,/[0-9]+ hr/)  ? substr($6,RSTART)+0 : 0 )
        mins = ( match($6,/[0-9]+ min/) ? substr($6,RSTART)+0 : 0 )
    }
    (hrs > 5) || (mins > 300)
' file
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55643180

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档