특정 행의 값을 기준으로 열 선택/추출

특정 행의 값을 기준으로 열 선택/추출

다음은 샘플 텍스트 파일입니다.

A B C D E F G
1 2 3 4 5 6 7
2 3 4 5 6 7 8
3 4 5 6 7 8 9

세 번째 행의 값인 2 3 4 5 6 7 8을 기반으로 특정 열을 추출하고 싶습니다. 세 번째 행에서 5보다 큰 값을 가진 모든 열을 추출하고 싶다고 가정해 보겠습니다. 마지막 3개 열이 됩니다. 따라서 내 목표는 다음을 선택하고 생성하는 것입니다.

E F G
5 6 7
6 7 8
7 8 9

이것은 내 코드입니다.

NR==3 {
    for (i=1; i<=NF; i++) {
        if ($i > 5)   x[j++] = i
    }
}
NR>= 1 {
  for (i=0 ;  i < j-1; i++ )
     printf("%s ",$x[i])
  printf("%s\n",$x[j-1])
}

그러나 이로 인해 다음과 같은 결과가 생성됩니다.

A B C D E F G
1 2 3 4 5 6 7
6 7 8
7 8 9

내가 놓친 게 무엇입니까?

답변1

다음을 수행할 수 있습니다.

code=$(
  awk '
    NR == 3 {
      for (i=1; i<=NF; i++)
        if ($i > 5) { printf "%s", sep "$" i; sep="," }
      exit sep == ""
    }' file
) &&
  awk "{print $code}" file

즉, awk동일한 파일에서 두 번 호출하는 것입니다. 첫 번째는 세 번째 줄을 읽어 두 번째 awk호출에 대한 코드를 구성합니다. 세 번째 줄을 처리한 후 종료되므로 전체 파일을 완전히 읽지 않습니다. 다음과 같은 결과가 출력되므로 $5,$6,$7다음 awk호출은 다음과 같습니다.

awk '{print $5,$6,$7}' file

답변2

공유할 또 다른 awk 솔루션이 있습니다.

cat > extract.columns.awk   
BEGIN {   
  infil=ARGV[1]  
    while (getline < infil > 0)  
      if (++n==3)  
      {  
        for(i=1;i<=NF;i++)  
            if ($(i) > 5) x[++j]=i  
    }  
close(infil)    
}  
{  
    for (i=1;i<j;i++)  
    printf("%s ",$x[i])  
    printf("%s\n",$x[j])  
}  

awk -f extract.columns.awk 파일

답변3

아래 코드에 따라 파일 이름을 두 번 언급하십시오.

awk 'NR == FNR{if(FNR == line) {for(i=1; i<=NF; i++) {if($i > lmt) a[i]} close(FILENAME)} next}
{for(i=1; i<=NF; i++) {for(i in a) {out = (out == "") ? $i : (out FS $i)}}
  print out; out=""}' line=3 lmt=5 file file

관련 정보