awk에서 여러 열을 연속 행으로 변환하는 방법

awk에서 여러 열을 연속 행으로 변환하는 방법

A.txt 파일이 있습니다(sep = \t, 첫 번째 열은 비어 있음).

    Cycle  A1  A2  B1
    1      4   5   2
    2      7   3   4
    3      3   2   5

\t이 파일을 새 파일 B.txt(9월 = ) 로 변환하고 싶습니다 .

Well  Cycle  Value
A1     1     4
A1     2     7
A1     3     3
A2     1     5
A2     2     3
A2     3     2
B1     1     2
B1     2     4
B1     3     5

몇 가지를 시도해 보았지만 awk '{for (i=1;i<=NF;i++) print $i}' 알 수가 없습니다. 이 작업을 수행하는 방법을 아는 사람이 있나요? 감사해요

답변1

아니요 awk, 하지만 다음을 사용하세요.밀러,주어진

$ cat file
    Cycle  A1  A2  B1
    1      4   5   2
    2      7   3   4
    3      3   2   5

그 다음에

$ mlr --pprint --ifs tab reshape -i A1,A2,B1 -o Well,Value then sort -f Well then reorder -f Well file
Well Cycle Value
A1   1     4
A1   2     7
A1   3     3
A2   1     5
A2   2     3
A2   3     2
B1   1     2
B1   2     4
B1   3     5

sort필요하지 않은 경우 이 단계를 생략할 수 있습니다.

Miller reshape명령은 필드 선택을 위해 정규식을 사용할 수도 있습니다.

reshape -r '[A-Z][1-9]' -o Well,Value

답변2

먼저 파일을 배열 배열로 로드한 AoA[colidx, rowidx] 다음 파일 청크의 끝에서 해당 데이터를 원하는 형식으로 재구성합니다.

노트:

  • 필드 구분 기호는 \t+빈 필드를 전달하는 대신 연속 탭을 반복하는 것입니다.
  • gsub()부분은 처음 n개의 후행 탭 문자를 제거합니다.
  • 이 코드는 파일 수만큼의 열과 행을 처리합니다. (메모리 허용)
awk -F '\t+' '
gsub(/^\t|\t$/, "") {$1=$1}
NR==1 {header = "Well" OFS $1 OFS "Value"}
{
  for(i=1; i<=NF; i++) {
    AoA[i, NR] = $(i)
  }
}
END {
  print header
  for(col=2; col<=NF; col++) {
    for(row=2; row<=NR; row++) {
      well  = AoA[col, 1]
      cycle = AoA[1, row]
      value = AoA[col, row]
      print well, cycle, value
    }
  }
}
' OFS='\t' -  | column -t

결과:

Well  Cycle  Value
A1    1      4
A1    2      7
A1    3      3
A2    1      5
A2    2      3
A2    3      2
B1    1      2
B1    2      4
B1    3      5

답변3

이는 헤더가 정적이고 미리 알려져 있어야 하며 잘 정렬되지 않는 (다소 조잡한) 접근 방식입니다.

$ awk -F'\t' -v OFS="\t" 'BEGIN{print "Well","Cycle","Value"}
                         NR>1{
                            cycle[NR]=$2;
                            a1[NR]=$3; 
                            a2[NR]=$4; 
                            b1[NR]=$5;
                        }
                        END{
                            for(line in cycle){
                                print "A1",cycle[line],a1[line]; 
                                print "A2",cycle[line],a2[line]; 
                                print "B1",cycle[line],b1[line]
                            }
                        }' file 
Well    Cycle   Value
A1  1   4
A2  1   5
B1  1   2
A1  2   7
A2  2   3
B1  2   4
A1  3   3
A2  3   2
B1  3   5

좋은 정렬이 필요한 경우 더 거친 정렬을 사용할 수 있습니다.

$ awk -F'\t' -vOFS="\t" 'BEGIN{print "Well","Cycle","Value"}
                         NR>1{
                            cycle[NR]=$2;
                            a1[NR]=$3; 
                            a2[NR]=$4; 
                            b1[NR]=$5;
                        }
                        END{
                            for(line in cycle){
                                print "A1",cycle[line],a1[line];
                            }
                            for(line in cycle){
                                print "A2",cycle[line],a2[line]; 
                            }
                            for(line in cycle){
                                print "B1",cycle[line],b1[line]
                            }
                        }' file 
Well    Cycle   Value
A1  1   4
A1  2   7
A1  3   3
A2  1   5
A2  2   3
A2  3   2
B1  1   2
B1  2   4
B1  3   5

관련 정보