다른 파일의 행을 사용하여 대용량 파일에서 열 선택

다른 파일의 행을 사용하여 대용량 파일에서 열 선택

다른 파일의 행을 기반으로 대용량 파일에서 열을 선택하고 싶습니다. 이 질문에 대한 답변은 여기에 있지만 두 솔루션 모두 작동하지 않습니다.

https://www.biostars.org/p/166527/

데이터.TXT

head0 head1 head2 head3 head4  
1 25 1364 22 13  
2 10 215 1 22  

목록.TXT

head0  
head4 

원하는 출력:

head0 head4  
1 13  
2 22

두 번째 솔루션의 첫 번째 명령이 작동합니다.

cat file1.txt | cut -f$(grep -wFf file2.txt TMP | cut -f1 | sed -e ':a' -e 'N' -e '$!ba' -e 's/\n/,/g') > OUTPUT cut: option requires an argument -- f

어떤 제안이 있으십니까?

감사해요

답변1

내 Mac에서도 같은 오류가 발생합니다.

  1. 파일이 탭으로 구분되어 있고 선행 또는 후행 공백이 없는지 확인해야 합니다.
  2. sed 명령은 다음으로 대체될 수 있습니다.paste -sd,
  3. 떠나다:

    cut -f"$(grep -wFf LIST.TXT TMP | cut -f1 | paste -sd,)" DATA.TXT 
    

그러나 awk 솔루션을 사용하면 더 깔끔하고 tmp 파일을 사용하지 않으며 공백을 더 잘 허용합니다.

awk -v OFS='\t' '
    NR == FNR {header[$1] = 1; next}
    FNR == 1 {for (i=1; i<=NF; i++) if ($i in header) column[i] = 1}
    {for (i in column) printf "%s" OFS, $i; print ""}
' headers file

잠시 실행한 후 작업 파이프라인(tmp 파일이 필요한 흰색 파이프라인)은 다음과 같습니다.

cut -f"$(head -1 DATA.TXT | tr '\t' '\n' | nl | grep -Fwf LIST.TXT | awk '{print $1}' | paste -sd,)" DATA.TXT

답변2

list.txt에 정의된 순서대로 열을 출력한다고 가정해 보겠습니다.

$ cat tst.awk
NR==FNR {
    name2out[$1] = ++numOutFlds
    next
}
FNR == 1 {
    for (inFldNr=1; inFldNr<=NF; inFldNr++) {
        outFldNr = name2out[$inFldNr]
        out2in[outFldNr] = inFldNr
    }
}
{
    for (outFldNr=1; outFldNr<=numOutFlds; outFldNr++) {
        inFldNr = out2in[outFldNr]
        printf "%s%s", $inFldNr, (outFldNr < numOutFlds ? OFS : ORS)
    }
}

$ awk -f tst.awk list.txt data.txt
head0 head4
1 13
2 22

관련 정보