입력 파일이 있습니다.
3.59717487E+05 3.40210880E+06 4075.32 7066.00 4075.32 7066 4075.322 2 a_final_psdm_LY1-1250_20160307
3.59725248E+05 3.40211860E+06 4063.53 7067.00 4063.53 7067 4063.527 2 a_final_psdm_LY1-1250_20160307
3.59733009E+05 3.40212840E+06 4051.73 7068.00 4051.73 7068 4051.731 2 a_final_psdm_LY1-1250_20160307
3.59740771E+05 3.40213820E+06 4039.94 7069.00 4039.94 7069 4039.936 2 a_final_psdm_LY1-1250_20160307
마지막 열을 가져와 변수(LY1-1250 섹션)를 정의해야 합니다. 이것이 내가 지금까지 가지고 있는 것입니다:
awk '
BEGIN{
if($NF !~ /LY1/){
print
}
else{
tag=$NF
print tag
}
}
하지만 이것은 나에게 tag=a_final_psdm_LY1-1250_20160307을 제공합니다.
태그=LY1-1250이 필요합니다.
쉘 스크립트에서 나는 이것을 할 것입니다
tag=`echo $NF sed... 어쩌구 저쩌구 |
그런데 awk에서는 표현을 평가하지 않는 것 같습니다.
답변1
"레이블"은 끝에서 두 번째 부분 이후의 부분이므로 _
간단히 필드 구분 기호로 사용할 수 있습니다.
$ awk -F_ '{if($(NF-1)~/LY1/){print $(NF-1)}else{print}}' file
LY1-1250
LY1-1250
LY1-1250
LY1-1250
또는 변수로 사용하십시오.
awk -F_ '{if($(NF-1)~/LY1/){tag=$(NF-1); print tag}else{print}}' file
귀하의 코드가 블록에 있는 이유를 이해할 수 없습니다 BEGIN{}
. 행을 읽기 전에 한 번만 실행되므로 NF
정의되지도 않습니다.
어쨌든 일반적인 경우 awk의 변수에 하위 문자열을 저장하는 방법은 substr
또는 을 사용하는 것입니다 sub
. 따라서 다음과 같이 할 수도 있습니다.
$ awk '{
if($NF~/LY1/){
tag=$NF;
sub(/.*LY1/,"LY1",tag);
sub(/_[^_]*$/,"",tag);
print tag
}
else{ print } }' file
LY1-1250
LY1-1250
LY1-1250
LY1-1250
답변2
조건을 잘못 이해하신 것 같습니다 awk
. 각 줄의 시작예상태. 여기에 좀 더... awk
-ward 방법이 있습니다.
awk '
/LY1/ {
tag=gensub(/_.*/,"","1",gensub(/.*LY1/,"LY1","1", $NF))
print tag
next
}
{
print
}' input.file
첫 번째 /LY1/
는 암시적 matches
조건입니다. 즉, 입력 줄이 정규식과 일치하는 경우에만 표현식이 실행됩니다. 표현식은 먼저 행의 모든 항목을 , 이하 및 포함으로 대체 LY1
하고 LY1
이를 변수 태그에 넣습니다. 그런 다음 레이블을 인쇄하고 next
- 문은 다른 모든 표현식을 건너뜁니다.이 기록을 위해.
그 다음에는 단순히 행을 있는 그대로 인쇄하는 무조건 표현식이 옵니다. 그러나 이전 표현식이 실행되면 호출되므로 실행되지 않습니다 next
.
답변3
이 시도:
awk '
{
if(!match($NF,"LY1[^_]*")){
print
}
else {
tag=substr($NF,RSTART,RLENGTH)
print tag
}
}' input.file
match()
정규식을 찾아보세요.
또한 이 함수는 정규식이 시작되고 끝나는 위치를 나타내는 RSTART
두 개의 특수 변수를 설정합니다.RLENGTH