헤더(첫 번째 행)가 다른 텍스트 파일("strings.txt")에 나열된 특정 문자열과 일치하는 텍스트 파일("columns.txt")에서 탭으로 구분된 열을 추출하고 싶습니다.
"columns.txt"는 다음과 같습니다.
rs2438689 rs54666437 rs9877702046 rs025436779...
0 0 0 1
1 1 2 2
0 1 2 0
... ... ... ...
"strings.txt"는 다음과 같습니다:
rs2438689
rs9877702046
...
출력 텍스트 파일 "output.txt"는 다음과 같아야 합니다(탭으로 구분).
rs2438689 rs9877702046...
0 0
1 2
0 2
... ...
awk를 사용하여 이를 수행하는 방법에 대한 제안이 있습니까? 감사합니다!
답변1
Awk 대신 쉼표로 구분된 열 이름 목록을 만들고 이를 strings.txt
s 목록으로 사용하려면 어떻게 해야 합니까?namedcol
csvtool
$ csvtool -t TAB -u TAB namedcol "$(paste -sd, < strings.txt)" columns.txt
rs2438689 rs9877702046
0 0
1 2
0 2
... ...
또는 csvcut/csvformat
Python을 기반으로 하는 유사한 것 csvkit
:
$ csvcut -tc "$(paste -sd, < strings.txt)" columns.txt | csvformat -T
rs2438689 rs9877702046
0 0
1 2
0 2
... ...
답변2
그리고perl
$ perl -F'\t' -lane 'if(!$#ARGV){ $h{$_}=1 }
else{ @i = grep { $h{$F[$_]} == 1 } 0..$#F if !$c++;
print join "\t", @F[@i]}' strings.txt columns.txt
rs2438689 rs9877702046
0 0
1 2
0 2
if(!$#ARGV){ $h{$_}=1 }
첫 번째 입력 파일의 경우 행 내용으로 키가 지정된 해시를 만듭니다.@i = grep { $h{$F[$_]} == 1 } 0..$#F if !$c++
두 번째 파일의 첫 번째 행에 대해 해시에서 일치하는 모든 열 이름의 색인화된 목록을 만듭니다.print join "\t", @F[@i]
일치하는 열 인쇄
답변3
개정하다이전 문제에 대한 나의 해결책:
awk -F '\t' -f script.awk strings.txt columns.txt
script.awk
어디
BEGIN { OFS = FS }
FNR == NR {
columns[$1] = 1
next
}
FNR == 1 {
for (i = 1; i <= NF; ++i)
if ($i in columns)
keep[i] = 1
}
{
nf = split($0, fields, FS)
$0 = ""
j = 0
for (i = 1; i <= nf; ++i)
if (i in keep)
$(++j) = fields[i]
print
}
여기서 블록은 FNR == NR
명령줄( ) strings.txt
에 나열된 첫 번째 파일을 읽을 때만 실행됩니다 . columns
키를 열 이름으로 사용하여 배열을 채웁니다 . 나머지 코드는 다음과 같습니다.다소간FNR == 1
현재 열이 ( 블록 에) 유지하려는 열인지 확인한다는 점을 제외하면 이전 솔루션과 동일합니다 .
해결하다댓글에 있는 질문:
항상 처음 6개 열을 복사하고 열 머리글을 잘라내 _
려면
FNR == 1 {
for (i = 1; i <= NF; ++i)
if ($i in columns)
keep[i] = 1
}
입력하다
FNR == 1 {
for (i = 1; i <= NF; ++i) {
sub("_.*", "", $i)
if (i <= 6 || $i in columns)
keep[i] = 1
}
}
답변4
아래 스크립트를 사용하면 오랫동안 잘 작동할 수 있습니다.
k=wc -l file1| awk '{print $1}'
for ((i=1;i<=$k;i++)); do for j in `cat file2`; do awk -v i="$i" -v j="$j" '$i == j {x=NR+k}(NR<=x){print $i}' file1; done ; done>final.txt
z=`wc -l final.txt| awk '{print $1}'`
for ((i=1;i<=$z;i++)); do j=$(($i+3)); sed -n ''$i','$j'p' final.txt >file_starting_with_$i.txt; i=$j; done
paste file_starting_with*
산출
rs2438689 rs9877702046
0 0
1 2
0 2