2016-06-06 3 views
1

나는 500 개의 열이있는 파일을 가지고 있으며 모든 파일에서 공통으로 $ 1을 인쇄하는 동안 각 열을 새 파일로 분할해야합니다. 내가 파일 대응을 추적 할 수있다, 그러나필드 이름을 파일 이름으로 설정하는 방법

1.txt 
ID ID 
aa aa 
bb bb 
cc cc 
dd dd 

2.txt 
ID F1 
aa 1 
bb 1 
cc 1 
dd 1 

.... 

: 아래 예제 파일이며, 나는 아래의 bash는/AWK 솔루션을 사용하여이 작업을 수행하기 위해 관리 :

ID F1 F2 F4 F4 
aa 1 2 3 4 
bb 1 2 3 4 
cc 1 2 3 4 
dd 1 2 3 4 

num=('1' '2' '3' '4') 
for i in ${num[@]}; do awk -F "\t" -v col="$i" '{print $1,$col}' OFS="\t"   
Input.txt > ${i}.txt; done 

으로 필요한 출력을 제공합니다 출력 파일 이름으로 사용 된 열은 필드 번호이지만 필드 이름은 아닙니다. 필드의 헤더를 접두사로 출력 파일 이름에 쓸 수 있습니까?

ID.txt 
ID ID 
aa aa 
bb bb 
cc cc 
dd dd 

F1.txt 
ID F1 
aa 1 
bb 1 
cc 1 
dd 1 
+0

, awk''의 단일 패스에서 수행 할 수 있지만, 500 열은 문제가 될 수 - 당신이 한 번에 그것을 할 최소한 500 개 파일을 열 수 있어야합니다 (내'ulimit -n'은 기본적으로 256입니다). 여러 번 통과해야 할 수도 있습니다 (2 ~ 99, 100-199, 200-299, 300-399, 400-499 등). –

+0

firs 줄을 읽고 use는 for 루프의 색인으로, 열을 계산하는 사용자 자신의 카운터 – Jerzyk

답변

1

귀하의 요구 사항이 올바르게 이해되면 귀하가 매우 가깝게 보입니다.

귀하의 예제 출력에서와 같이 헤더를 유지해야하는 경우, 단지 ;next을 제거 편집

num=('1' '2' '3' '4') 
for i in ${num[@]}; do 
    echo "i=$i" 
    awk -F "\t" -v col="$i" -v OFS="\t" ' 
    NR==1{fName=$(col+1)".out";next} 
    {print $1,$(col+1) > fName}' data.txt 
done 

1>cat F1.out 
aa  1 
bb  1 
cc  1 
dd  1 

. . . . 

1>cat F4.out 
aa  4 
bb  4 
cc  4 
dd  4 

보십시오. 이름이 같은 여러 개의 열이있는 경우


편집 2

대신 >> fName를 사용하여 동일한 파일에 데이터를 추가 할 수 있습니다. 이 기술로 경고하는 한 마디. > fName을 사용하면 스크립트를 다시 실행할 때마다 파일이 "다시 시작"됩니다. 그러나 >>을 사용하면 스크립트를 실행할 때마다 각 파일에 추가됩니다. 다운 스트림 프로세스에 문제가 발생할 수 있습니다 .- 그래서 ... 이전 스크립트 실행을 정리하는 코드를 추가해야합니다. 여기


, 우리는 awk> fName을 사용하여 파일에 출력을 쓸 수 있다는 사실에 의존하고 (fName는 COL의 값 (NUM) +1로 정의 된 경우 (첫 번째 스킵

그리고 하루에 수천 번이 작업을 수행하려는 경우 awk을 한 번 읽고 내부 루프의 모든 출력을 생성하도록 위의 주석 당 최적화하는 것이 좋습니다. 그러나 if 이 작업을 몇 번만하면됩니다. 'unix/linux 도구를 사용하여 작업을 관리 가능한 부분으로 분해하십시오'는 완벽하게 맞습니다.

IHTH

원칙적으로
+2

모든 줄 끝에서'close (fName)'을 놓치지 마십시오. 그렇지 않으면 파일 설명자가 부족할 수 있습니다. – hek2mgl

+0

@ hek2mgl : 흠 .. 내 경험에 의하면,''> fName'은'awk' 호출의 수명 동안 만 활성 상태로 남아 있습니다. 한 번에 하나의 열만 처리하는 것처럼 작동하지 않습니까? 감사와 행운을 빕니다. – shellter

+0

열 이름이 다른 경우 작동합니다. 필자는 awk이 여러 번 열어서 파일을 열어 둘 수 있습니다. n 개의 다른 열> 파일 설명자가있는 경우 실패합니다. – hek2mgl

2

당신은 하나 awk 스크립트에서 모든 것을 할 수 있습니다. 첫 번째 행을 처리 할 때 모든 열 머리글을 배열에 넣습니다. 그런 다음 라인을 처리 할 때 그 배열의 파일 이름에 루프를 작성합니다.

awk -F'\t' 'NR == 1 { split($0, filenames) } 
    {for (col = 1; col <= NF; col++) { 
     file= filenames[col] ".txt"; 
     print $1, $col >> file; 
     close(file) } }' Input.txt 
+1

모든 줄 다음에'($ filenames [col])'를 놓치지 마십시오. 그렇지 않으면 파일 설명자가 부족할 수 있습니다. – hek2mgl

+1

요즘 대부분의 시스템에는 수천 개의 디스크립터가 있기 때문에 문제가 될 수는 없지만 추가했습니다. 나는 또한'>>'로 바뀌 었습니다. 파일을 닫을 때부터 필요합니까? – Barmar

+1

대부분의 파일은 요즘 수백만 줄이 있습니다.) – hek2mgl

관련 문제