대문자로 시작하는 열을 추출한 후 소문자로 시작하는 다음 열을 추출합니다.

대문자로 시작하는 열을 추출한 후 소문자로 시작하는 다음 열을 추출합니다.

밑줄(_)로 구분된 여러 열이 있는 파일이 있습니다.

대부분의 열은 첫 번째 문자가 대문자로 시작하고 일부 열은 소문자로 시작합니다.

대문자로 시작하고 다음 열은 소문자로 시작하는 각 행의 문자열을 추출할 계획입니다. 이는 모든 줄에서 적어도 한 번 발생합니다.(업데이트: 첫 번째 게임만 있었다면 좋았을 텐데). 까다로운 부분은 이것이 모든 행의 동일한 열에서 발생하지 않는다는 것입니다.

예를 들어:

Today_is_a_Good_Day
It_Doesnt_rain
i_dont_Like_rainy_day

원하는 출력:

Today_is
Doesnt_rain
Like_rainy

grep/sed/awk 또는 다른 명령을 사용하여 이러한 유형의 텍스트 추출을 수행하는 방법이 있습니까?

내 문제에 대한 비슷한 해결책을 찾으려고 노력했지만 찾지 못했습니다.

업데이트 : 적어도있을 것입니다

답변1

grepPCRE 및 다음 에서 지원되는 구현 -o:

$ grep -P -o '(?<![^_])\p{Lu}[^_]*_\p{Ll}[^_]*' < your-file
Today_is
Doesnt_rain
Like_rainy

(지원하지 않는 경우 대체할 수 있습니다 grep -P.)pcregrepgrep-P

u이것은 대문자 , 그 L뒤에 0개 이상의 non- s, 소문자 및 또 다른 0개 이상의 non- s 가 이어지는 순서이며 , 전체는 뒤에 non-가 없는 경우에만 일치합니다 (예: , 그 뒤에 또는 행의 시작).__lL___

그러면 일치하는 항목이 각각 한 줄에 인쇄됩니다. 각 행의 첫 번째 일치 항목으로 제한하려면 다르게 수행할 수 있습니다.

grep -P -o '^(.*?_)??\K\p{Lu}[^_]*_\p{Ll}[^_]*' < your-file

각 줄의 마지막 일치 항목은 동일하지만 앞부분을 차지하는 부분에 탐욕스러운 버전의 연산자를 사용합니다.

grep -P -o '^(.*_)?\K\p{Lu}[^_]*_\p{Ll}[^_]*' < your-file

답변2

$ grep -o '[[:upper:]][[:alpha:]]*_[[:lower:]][[:alpha:]]*' file
Today_is
Doesnt_rain
Like_rainy

이는 대문자로 시작하고 그 뒤에 임의 개수의 알파벳 문자, 밑줄, 소문자 및 (아마도) 더 많은 알파벳 문자가 오는 문자열을 추출합니다.

그러나 일치 항목이 여러 개인 경우 위 코드는 행당 여러 일치 항목을 추출합니다.

다음 sed명령에는 이 문제가 없습니다.마지막각 줄에는 다음과 같은 문자열이 있습니다.)

$ sed -n 's/.*\([[:upper:]][[:alpha:]]*_[[:lower:]][[:alpha:]]*\).*/\1/p' file
Today_is
Doesnt_rain
Like_rainy

답변3

awk 메서드

awk -F'_' -v OFS='_' '{
    for (i=1; i<NF; i++) {
        if ($i ~ /^[[:upper:]]/ && $(i+1) ~ /^[[:lower:]]/) {
            print $i, $(i+1)
            break
        }
    }
}' file

break첫 번째 일치 항목만 인쇄되는지 확인하세요 .

답변4

sed 's/.*\([A-Z][^_]*_[a-z][^_]*\).*/\1/' <your-file

편집: Greedy sed가 마지막 일치를 제공합니다. 첫 번째로 일치하는 awk 솔루션:

awk '{match($0,/([A-Z][^_]*_[a-z][^_]*)/,a); print a[1]}' <your-file

관련 정보