정규식을 개선하기 위해 영화 데이터베이스 문제를 연구 중인데 이것이 바로 제가 겪고 있는 문제입니다. 내 데이터세트는 다음과 같습니다.
영화 이름(가변 공백 및 탭) 연도
영화 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