我需要重新编目所有运行时间超过 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