Linux의 파일에 탭으로 구분된 큰 행렬이 있습니다.
Name ID ABC12 ABCD12 ABCD123 ABCD1234
ABC12 123456 XX YY ZZ JJ
ABC12 123456 XX YY ZZ JJ
ABCD12 123456 XX YY ZZ JJ
ABCD12 123456 XX YY ZZ JJ
ABCD123 123456 XX YY ZZ JJ
ABCD123 123456 XX YY ZZ JJ
ABCD1234 123456 XX YY ZZ JJ
ABCD1234 123456 XX YY ZZ JJ
이 행렬을 첫 번째 열의 일치 항목을 기반으로 별도의 파일로 분할하고 싶습니다. [이 파일은 용량이 커서 열 수를 셀 수 없습니다.]
예상 출력:
파일 1;
Name ID ABC12
ABC12 123456 XX
ABC12 123456 XX
파일 2;
Name ID ABCD12
ABCD12 123456 YY
ABCD12 123456 YY
파일 3;
Name ID ABCD123
ABCD123 123456 ZZ
ABCD123 123456 ZZ
파일 4;
Name ID ABCD1234
ABCD1234 123456 JJ
ABCD1234 123456 JJ
답변1
충분히앗해결책:
awk 'NR==1{ len=split($0,a_pos); for(i=1;i<=len;i++) a_keys[a_pos[i]]=i }
NR>1{ if(!r[$1]++) { fn="file"++c; print "Name\tID\t"$1 > fn }
print $1,$2,$(a_keys[$1]) > fn
}' OFS='\t' file
len=split($0,a_pos)
- 첫 번째 행을 "키" 배열(a_pos
정수로 인덱스된 배열) 로 분할합니다.for(i=1;i<=len;i++) a_keys[a_pos[i]]=i
- 문자열 키로 인덱싱할 배열로 뒤집기a_pos
(추가 처리를 위해)a_keys
fn="file"++c
- 구성 파일 이름
결과 보기:
for f in file[0-9]*; do (echo "$f"; cat "$f"; echo); done
출력( file1
, file2
및 연속 file3
형 file4
):
file1
Name ID ABC12
ABC12 123456 XX
ABC12 123456 XX
file2
Name ID ABCD12
ABCD12 123456 YY
ABCD12 123456 YY
file3
Name ID ABCD123
ABCD123 123456 ZZ
ABCD123 123456 ZZ
file4
Name ID ABCD1234
ABCD1234 123456 JJ
ABCD1234 123456 JJ
답변2
당신이 사용할 수있는 awk
:
awk 'NR>1{if ($1!=p){N="file"++C; print "Name\tID\t"$1 >N};
print $1,$2,$(C+2)>N}{p=$1}' infile.txt
답변3
제가 생각할 수 있는 가장 간단한 방법은 첫 번째 줄을 변수로 저장하고 나머지는 필요에 따라 인쇄하는 것입니다. 그러나 이를 위해서는 전체 입력 파일을 메모리에 저장해야 합니다.
#!/bin/gawk -f
{
if(NR==1){
header[1]=$1;
header[2]=$2;
for(i=3;i<=NF;i++){
header[$i]=i;
}
}
else{
data[$1][NR]=$2"\t"$(header[$1]);
}
}
END{
OFS="\t";
for(i in data){
print header[1],header[2],i > i".txt"
for(k in data[i]){
print i,data[i][k] >> i".txt"
}
}
}
스크립트를 foo.awk
실행 파일( chmod a+x foo.awk
)로 저장하고 파일에서 실행합니다.
foo.awk file
답변4
용법: ./split_matrix.awk input.txt
#!/usr/bin/awk -f
BEGIN {
cnt = 1;
}
NR == 1 {
for(i = 3; i <= NF; i++) {
headers[$i] = i;
}
}
NR > 1 {
if( ! file_names[$1]) {
file_names[$1] = cnt++;
printf "%s %s %s\n", "Name", "ID", $1 > "file_"file_names[$1];
}
printf "%s %s %s\n", $1, $2, $headers[$1] >> "file_"file_names[$1];
}
시험
입력하다
Name ID ABC12 ABCD12 ABCD123 ABCD1234
ABC12 123456 XX YY ZZ JJ
ABC12 123456 XX YY ZZ JJ
ABCD12 123456 XX YY ZZ JJ
ABCD12 123456 XX YY ZZ JJ
ABCD123 123456 XX YY ZZ JJ
ABCD123 123456 XX YY ZZ JJ
ABCD1234 123456 XX YY ZZ JJ
ABCD1234 123456 XX YY ZZ JJ
산출( tail -n +1 -- file*
파일 이름과 파일 내용을 인쇄하기 위해 이 트릭을 찾았습니다.여기)
==> file_1 <==
Name ID ABC12
ABC12 123456 XX
ABC12 123456 XX
==> file_2 <==
Name ID ABCD12
ABCD12 123456 YY
ABCD12 123456 YY
==> file_3 <==
Name ID ABCD123
ABCD123 123456 ZZ
ABCD123 123456 ZZ
==> file_4 <==
Name ID ABCD1234
ABCD1234 123456 JJ
ABCD1234 123456 JJ