Perl или Awk: время показа фильма больше 5 часов - PullRequest
2 голосов
/ 12 апреля 2019

Мне нужно заново каталогизировать все фильмы со временем выполнения более 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 или однострочный, который бы: * Вывести всю строку, если * Количество "мин" больше 300 или * Количество "часов" больше 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

Шаблоны 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.*\)/

Есть ли более простой и лаконичный способ?

Ответы [ 5 ]

4 голосов
/ 12 апреля 2019

Вместо того, чтобы пытаться сделать все это с помощью одного регулярного выражения монстра, я думаю, что разделение его на несколько разных частей более читабельно и легче для понимания, когда вы вернетесь к нему позже.Не нужно подавать стереотип 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, и печатает только те совпадающие строки.

2 голосов
/ 12 апреля 2019

Поскольку 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
2 голосов
/ 12 апреля 2019

Вы можете использовать регулярные выражения с группами захвата с 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.) :
0 голосов
/ 12 апреля 2019

пусть ваши данные в файле '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 "@F\n"}' d
0 голосов
/ 12 апреля 2019

Вы также можете использовать 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.) :
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...