awk: 첫 번째 행의 동일한 열에 있는 문자와 일치하지 않는 경우 지정된 행과 열의 문자를 바꿉니다.

awk: 첫 번째 행의 동일한 열에 있는 문자와 일치하지 않는 경우 지정된 행과 열의 문자를 바꿉니다.

나는 수년 동안 노력해 왔지만 가까이 가지 못했습니다. awk를 사용하면 모든 열의 > 1인 모든 행의 모든 ​​'*'를 '-'로 바꾸는 것은 어떻습니까? 단, 행 1의 해당 열이 '*'가 아닌 경우에만 가능합니까?

입력 예:
a|s|d|f|g|*|A|*|*|g|c|a|*|A|*
a|*|*|f|g|*|*|*|*|g|c|a|*|A|*
*|s|*|f|g|*|a|t|*|g|c|a|*|A|*
a|s|d|*|g|*|T|*|C|g|c|a|a|A|T

출력 예
a|s|d|f|g|*|A|*|*|g|c|a|*|A|*
a|-|-|f|g|*|-|*|*|g|c|a|*|A|*
-|s|-|f|g|*|a|t|*|g|c|a|*|A|*
a|s|d|-|g|*|T|*|C|g|c|a|a|A|T

답변1

헤더 행에서 "*"가 아닌 모든 항목을 검색해야 합니다.
"none" 열은 *배열에 저장될 수 있습니다 a[].
다음 모든 행에 대해 다음 행에만 존재합니다.a[] 가능한변화가 필요합니다.

이는 다음과 같이 구현될 수 있습니다.

awk -F'|' 'BEGIN{OFS=FS}
           NR==1 {
                   for(i=1;i<=NF;i++) if( $i != "*" ) a[i]
                 } 
           NR>1  {
                   for(i in a)        if( $i == "*" ) $i="-"
                 } 
           1
          ' file

a|s|d|f|g|*|A|*|*|g|c|a|*|A|*
a|-|-|f|g|*|-|*|*|g|c|a|*|A|*
-|s|-|f|g|*|a|t|*|g|c|a|*|A|*
a|s|d|-|g|*|T|*|C|g|c|a|a|A|T

이는 필요한 최소한의 변경 사항을 구현합니다. 가장 빨라야합니다.

답변2

한 가지 가능한 접근 방식(아마도 최선은 아닐 것임)

awk -F'|' '
  BEGIN{OFS=FS} 
  NR==1 {
    for(i=1;i<=NF;i++) if($i=="*") a[i]
  } 
  {
    for(i=1;i<=NF;i++) if($i=="*" && !(i in a)) $i="-"
  } 
  1
' file
a|s|d|f|g|*|A|*|*|g|c|a|*|A|*
a|-|-|f|g|*|-|*|*|g|c|a|*|A|*
-|s|-|f|g|*|a|t|*|g|c|a|*|A|*
a|s|d|-|g|*|T|*|C|g|c|a|a|A|T

관련 정보