이 균일하지 않은 데이터 세트에서 영화 제목을 추출하기 위한 전략은 무엇입니까?

이 균일하지 않은 데이터 세트에서 영화 제목을 추출하기 위한 전략은 무엇입니까?

정규식을 개선하기 위해 영화 데이터베이스 문제를 연구 중인데 이것이 바로 제가 겪고 있는 문제입니다. 내 데이터세트는 다음과 같습니다.

영화 이름(가변 공백 및 탭) 연도
영화 1(그 사이에 공백이 있거나 여러 개가 있을 수 있습니다) (가변 공백과 탭은 \t+ 또는 여러 개의 공백 또는 단일 공백이 될 수 있습니다.>첫해
영화 2(그 사이에 공백이 있거나 여러 개가 있을 수 있습니다) (가변 공백과 탭은 \t+ 또는 여러 개의 공백 또는 단일 공백이 될 수 있습니다.>두 번째 해
영화 3(그 사이에 공백이 있거나 여러 개가 있을 수 있습니다) (가변 공백과 탭은 \t+ 또는 여러 개의 공백 또는 단일 공백이 될 수 있습니다.>3년차
영화 4(그 사이에 공백이 있거나 여러 개가 있을 수 있습니다) (가변 공백과 탭은 \t+ 또는 여러 개의 공백 또는 단일 공백이 될 수 있습니다.>4학년

모든 영화의 이름을 추출하고 싶습니다. 제가 이 일을 하면서 겪었던 어려움은 다음과 같습니다.

1: 구분 기호는 가변적입니다. 콜론이나 고유한 것인 경우 awk 명령을 사용하여 다음과 같이 추출합니다 awk -F 'separator' '{print $1}'
이 경우 단일 공백, 둘 이상의 공백 또는 \t의 조합이 될 수 있습니다. 또는 공백.

2: 구분 기호가 \t인 줄의 경우 영화 이름에 포함되지 않으므로 \t를 사용하여 추출할 수 있습니다. 그런데 구분자가 공백 1개이거나 공백 2개이면 어떻게 될까요? 영화 제목에 쉽게 나타날 수 있습니다. 이런 상황에서는 어떻게 해야 할지 모르겠습니다.

나는 이 질문이 매우 엄격하고 구체적이라는 것을 알고 있습니다. 하지만 앞서 설명했듯이 여기서는 꽤 당황스럽습니다. 이 문제를 해결할 방법이 생각나지 않습니다.

목표를 달성하는 데 사용할 수 있는 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

관련 정보