두 일치 문자열 중 하나라도 일치하는 경우 줄을 추출하는 방법은 무엇입니까?

두 일치 문자열 중 하나라도 일치하는 경우 줄을 추출하는 방법은 무엇입니까?

아래와 같이 국가 이름이 포함된 몇 줄의 정보가 있는 파일이 있습니다.

$cat country.txt

max_china_clean_foo
man_india_raw_bar
max_us_clean_bax
max_uk_raw_bar
max_canada_raw_foo
max_au_clean_bar

이 파일에서 국가 이름만 추출하고 싶습니다. 현재 for 루프에서 국가 이름을 추출하기 위해 아래 코드를 사용하고 있습니다.

val=${val#*_}
val=${val%_clean*}
echo $val

하지만 생성된 출력에는 국가 이름만 있으므로 china, us아래와 au같이 나머지 국가를 추출하려면 약간 수정하여 유사한 코드를 반복해야 합니다.

val=${val#*_}
val=${val%_raw*}
echo $val

이것은 명확한 코딩 방법이 아닙니다. 따라서 clean또는 raw문자열이 포함된 모든 줄에서 국가 이름을 추출하려면 여러분의 도움이 필요하다는 것을 알고 있습니다.

두 개의 일치 키로 모든 국가 이름을 추출하기 위해 awk 또는 sed를 사용하는 방법이 있습니까? 내 출력은 다음과 같아야합니다

china
india
us
uk
canada
au

답변1

텍스트를 처리하기 위해 쉘 루프를 사용하지 않을 것입니다.

여기서는 다음과 같이 할 수 있습니다.

cut -d _ -f 2 < country.txt

또는 입력에 _문자가 없는 줄이 포함될 수 있는 경우:

awk -F _ 'NF >= 2 {print $2}' < country.txt

국가 이름에 문자가 포함될 수 있고 그 대신 첫 번째 항목과 첫 번째 항목 사이 또는 그 이후 _의 줄 부분을 반환하려는 경우 다음을 수행할 수 있습니다.__raw_clean

perl -ne 'print $1 if s/^[^_]*_(.*?)_(clean|raw)/' < country.txt

또는 GNU를 사용하면 다음과 같습니다 grep.

grep -Po '^[^_]*_\K.*?(?=_clean|_raw)' < country.txt

-P(PCRE 지원으로 구축된 경우 ) grep정규식은 Perl과 호환됩니다. 해당 정규식에서 \K일치하는 문자열의 시작을 재설정하고 (?=...)미리보기 연산자입니다. 즉, ...일치하는 부분에 해당 부분을 포함하지 않고 문자열의 나머지 부분이 일치하는지 확인합니다. 일치하는 부분을 출력 -o하므로 여기서는 탐욕스럽지 않은 것과 동일한 위와 일치하는 것을 인쇄합니다 . 즉, 가능한 한 짧은 0개 이상의 문자 시퀀스입니다. 이 경우 0개 이상의 밑줄 시퀀스가 ​​뒤따릅니다( ) 줄의 시작 부분에서 발견되며 ( ) 뒤에 밑줄이 오고 그 뒤에 또는 가 따른다고 가정합니다 .grep.*?.*[^_]*^_raw_clean

를 사용하면 pcregrep다음과 같이 작성할 수도 있습니다.

pcregrep -o1 '^[^_]*_(.*?)_(clean|raw)'

를 사용하면 -o1첫 번째 와 일치하는 부분을 인쇄합니다 (...).

답변2

awk 스타일의 방법은 다음과 같습니다.

awk -F'_' '/clean|raw/{ print $2}'

관련 정보