밑줄(_)로 구분된 여러 열이 있는 파일이 있습니다.
대부분의 열은 첫 번째 문자가 대문자로 시작하고 일부 열은 소문자로 시작합니다.
대문자로 시작하고 다음 열은 소문자로 시작하는 각 행의 문자열을 추출할 계획입니다. 이는 모든 줄에서 적어도 한 번 발생합니다.(업데이트: 첫 번째 게임만 있었다면 좋았을 텐데). 까다로운 부분은 이것이 모든 행의 동일한 열에서 발생하지 않는다는 것입니다.
예를 들어:
Today_is_a_Good_Day
It_Doesnt_rain
i_dont_Like_rainy_day
원하는 출력:
Today_is
Doesnt_rain
Like_rainy
grep/sed/awk 또는 다른 명령을 사용하여 이러한 유형의 텍스트 추출을 수행하는 방법이 있습니까?
내 문제에 대한 비슷한 해결책을 찾으려고 노력했지만 찾지 못했습니다.
업데이트 : 적어도있을 것입니다
답변1
grep
PCRE 및 다음 에서 지원되는 구현 -o
:
$ grep -P -o '(?<![^_])\p{Lu}[^_]*_\p{Ll}[^_]*' < your-file
Today_is
Doesnt_rain
Like_rainy
(지원하지 않는 경우 대체할 수 있습니다 grep -P
.)pcregrep
grep
-P
u
이것은 대문자 , 그 L
뒤에 0개 이상의 non- s, 소문자 및 또 다른 0개 이상의 non- s 가 이어지는 순서이며 , 전체는 뒤에 non-가 없는 경우에만 일치합니다 (예: , 그 뒤에 또는 행의 시작)._
_
l
L
_
_
_
그러면 일치하는 항목이 각각 한 줄에 인쇄됩니다. 각 행의 첫 번째 일치 항목으로 제한하려면 다르게 수행할 수 있습니다.
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