다른 파일의 행을 기반으로 대용량 파일에서 열을 선택하고 싶습니다. 이 질문에 대한 답변은 여기에 있지만 두 솔루션 모두 작동하지 않습니다.
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에서도 같은 오류가 발생합니다.
- 파일이 탭으로 구분되어 있고 선행 또는 후행 공백이 없는지 확인해야 합니다.
- sed 명령은 다음으로 대체될 수 있습니다.
paste -sd,
떠나다:
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