从这个不统一的数据集中提取电影名称的策略?

从这个不统一的数据集中提取电影名称的策略?

我正在研究电影数据库问题以改进正则表达式,这就是我遇到的问题。我的数据集如下所示:

电影名称(可变空格和制表符)年份
电影1(它们之间可以有空格或多个空格)(可变空格和制表符可以是 \t+ 或多个空格或单个空格>第一年
电影2(它们之间可以有空格或多个空格)(可变空格和制表符可以是 \t+ 或多个空格或单个空格>第二年
电影3(它们之间可以有空格或多个空格)(可变空格和制表符可以是 \t+ 或多个空格或单个空格>第三年
电影4(它们之间可以有空格或多个空格)(可变空格和制表符可以是 \t+ 或多个空格或单个空格>第四年

我想提取所有电影的名称。这些是我在做这件事时面临的挑战:

1:分隔符是可变的。如果它是冒号或独特的东西,我会使用 awk 命令来提取它们,就像这样 awk -F 'separator' '{print $1}'
在这种情况下,它可以是单个空格、两个或多个空格或 \ 的组合t 或空格。

2:对于那些分隔符为 \t 的行,我可以使用 \t 来提取它,因为它不包含在电影名称中。但如果分隔符是一个空格或两个空格怎么办?它们很容易出现在电影的名称中。在这些情况下,我不知道该怎么办。

我知道这个问题非常严格和具体。但正如我之前所描述的,我在这里受到了很大的阻碍。我想不出任何办法来解决这个问题。

是否有 grep/sed/awk 与 reg-ex 的任何组合可以用来实现目标?

答案1

使用gawk并假设年份总是结束记录:

awk -F"[0-9]{4}$" '{print $1}' movies

答案2

重击:

while read -r line; do
    if [[ $line =~ (.*)[[:blank:]]+[0-9]{4}$ ]]; then
        echo "${BASH_REMATCH[1]}"
    fi
done < data

sed:

sed 's/[[:blank:]]\+[0-9]\{4\}$//' < data

答案3

这确实很简单。只要最后一个字段(年份)不包含任何空格(从您的问题中不清楚,但我假设情况确实如此),您所需要做的就是删除最后一个字段。例如:

$ cat movies
Casablanca  1942
Eternal Sunshine        of the Spotless Mind            2004
He Died with a Felafel in His Hand                       2001
The Blues Brothers 1980

因此,如果您只想打印标题,可以使用:

$ perl -lpe 's/[^\s]+$//' movies
Casablanca  
Eternal Sunshine        of the Spotless Mind            
He Died with a Felafel in His Hand                       
The Blues Brothers 

$ sed 's/[^ \t]*$//' movies 
Casablanca  
Eternal Sunshine        of the Spotless Mind            
He Died with a Felafel in His Hand                       
The Blues Brothers 

或者,也折叠标题中的空白:

$ sed -r 's/[\t ]+/ /g;s/[^ \t]*$//' movies 
Casablanca 
Eternal Sunshine of the Spotless Mind 
He Died with a Felafel in His Hand 
The Blues Brothers 

$ perl -lpe 's/\s+/ /g;s/[^\s]+$//' movies
Casablanca 
Eternal Sunshine of the Spotless Mind 
He Died with a Felafel in His Hand 
The Blues Brothers 

$ awk '{for(i=1;i<NF-1;i++){printf "%s ",$i} print $(NF-1)}' movies
Casablanca 
Eternal Sunshine of the Spotless Mind 
He Died with a Felafel in His Hand 
The Blues Brothers 

如果年份始终为 4 位数字,则可以使用

$ perl -lpe 's/....$//' movies 
Casablanca 
Eternal Sunshine of the Spotless Mind 
He Died with a Felafel in His Hand 
The Blues Brothers 

或者

$ perl -lpe 's/\s+/ /g;s/....$//' movies 
Casablanca 
Eternal Sunshine of the Spotless Mind 
He Died with a Felafel in His Hand 
The Blues Brothers 

或者

$ while read line; do echo ${line%%????}; done < movies|od -c 
Casablanca 
Eternal Sunshine of the Spotless Mind 
He Died with a Felafel in His Hand 
The Blues Brothers 

答案4

这应该删除最后一个数字字符及其前面的制表符和空格:

sed -e 's#[\t ]*[0-9]*$##' movies.txt

相关内容