
아래와 같이 국가 이름이 포함된 몇 줄의 정보가 있는 파일이 있습니다.
$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}'