Perl 或 Awk:匹配影片运行时间大于 5 小时



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

示例数据:

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片段或单行代码可以:*打印整行,如果* # 的 "min" 大于 300 或* # 的 "hr(s(" 大于 5

像这样:

perl -F\t -ane 'print if $F[6] <substring or capture group representing minutes> > 300' file.csv

awk接近

awk -F't' '$6 ~ /^.*(.*[3-9][[:digit:]]{2}[[:space:]]+min.*)/ {print}' minutes.csv

正则表达式模式:大于 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.*)/

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

与其尝试使用一个怪物正则表达式来完成所有操作,我认为将其拆分为几个不同的正则表达式更易读,稍后再回到它时更容易理解。无需灌输 perl 看起来像线路噪声的刻板印象......

$ perl -F\t -ane 'print if ($F[5] =~ /(d+) hr./ && $1 > 5) || ($F[5] =~ /(d+) min./ && $1 > 300)' input.tsv

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

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

> 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.) :

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

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

但是,如果您愿意,可以将其编写为 2 个单独的测试:

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

您也可以使用 awk

> awk -F'[^0-9]+' '/min./&&$(NF-1)>300||/hr./&&$(NF-/min./-1)>5' catalog
239835  92075   Moonlighting, seasons one and two   NVIDEO  DVD 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.) :
856287  208624  The Munsters.   NVIDEO  DVD 12 videodiscs (approximately 33 hr.) :
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.) :

让你的数据在'd'文件中,

perl -F"(|)" -ane '$t=@F[$#F-1]; $t =~ s/.*?(d+s*(?:min|hr.)).*/1/; if($t =~ /min/ && $t>300 or $t =~ /hr./ && $t>5) {print "@Fn"}' d

最新更新