파일이 있습니다 A.txt
(9월 = \t
).
Cycle Well Value Target
1 A1 5.07368111264623 EC
1 A1 3.06982862746599 FT
1 A1 2.46545646544623 EC
두 번째 파일 B.txt
(sep = \t
,첫 번째 열은 비어 있습니다.):
Well Fluor Target Content Sample
A1 Cy5 EC Unkn-01 2060563935
A1 Cy5 FT Unkn-09 2156515156
Content
다음의 경우에 추가하고 싶은 B.txt
열을 추가하고 싶습니다 .A.txt
둘 다 Well
Target
두 파일의 데이터가 동일하고 결과를 ( C.txt
sep = \t
)로 출력합니다.
Cycle Well Value Target Content
1 A1 5.07368111264623 EC Unkn-01
1 A1 3.06982862746599 FT Unkn-09
1 A1 2.46545646544623 EC Unkn-01
나는 다음과 같은 것을 시도합니다 :
awk -F"\t" 'FNR==NR{if (a[$2]) {a[$2]=a[$2] "\t" $7} else {a[$2]=$7}} NR>FNR{split($0,f,"\t"); if (a[f[4]]) $0=$0 "\t" a[f[4]]; print}'
그러나 그것은 작동하지 않았습니다. 이 작업을 수행하는 방법을 아시나요?
정확한:
- 템플릿으로 사용된 첫 번째 파일(A.txt)에는 동일한 기공과 타겟을 가진 여러 개의 리그닌이 있습니다.
- B.txt에는 동일한 구멍/대상 조합이 있는 행이 하나만 있습니다.
- 파일 A와 파일 B가 일치하는 패턴을 갖지 않는 것은 불가능합니다.
답변1
첫 번째 솔루션은 다음을 사용합니다.GNU awk또는POSIX awk
편집하다:~처럼에드 모튼awk
GNU 전용 지원에 대한 원래 답변이 잘못되었다고 그의 의견에 썼습니다 . (GNU 문서와 POSIX 문서의 표현은 약간 혼란스럽습니다.)
GNU 문서 awk
의 제목다차원 배열POSIX 준수를 지원합니다 awk
. 바라보다https://pubs.opengroup.org/onlinepubs/000095399/utilities/awk.html"다차원" 또는 을 검색하세요 SUBSEP
. 이러한 배열은 실제로 1차원입니다.
GNU awk
도 지원합니다배열의 배열이것은 진정한 다차원 배열입니다.
이 명령 버전에는 GNU가 필요합니다 awk
.
awk -F"\t" 'NR == FNR { a[$2][$4] = $5; next } { print $0, a[$2][$4] }' B.txt A.txt > C.txt
POSIX 호환 변형(*)은 모든 것과 awk
호환되어야 합니다.
awk -F"\t" 'NR == FNR { a[$2,$4] = $5; next } { print $0, a[$2,$4] }' B.txt A.txt > C.txt
둘 다 인쇄
Cycle Well Value Target
1 A1 5.07368111264623 EC Unkn-01
1 A1 3.06982862746599 FT Unkn-09
1 A1 2.46545646544623 EC Unkn-01
질문에 따르면 Well/Target 키가 파일에서 고유하기 때문에 파일의 데이터는 B.txt
배열에 저장됩니다 . a
그런 다음 이 데이터는 파일의 데이터에 추가됩니다 A.txt
.
필드 구분 기호를 명시적으로 지정해야 합니다. 그렇지 않으면 awk
빈 열/값이 무시됩니다.
이 솔루션은 고정된 열 번호를 사용하여 일치하거나 인쇄할 열을 식별합니다.
편집하다:\t
인덱스 표현식과 구분 기호를 명시적으로 결합하는 다음 솔루션은 위에 표시된 POSIX 호환 솔루션(*)에 비해 이점을 제공하지 않습니다.
awk -F"\t" 'NR == FNR { a[$2 "\t" $4] = $5; next } { print $0, a[$2 "\t" $4] }' B.txt A.txt > C.txt
이는 구문을 설정 SUBSEP = "\t"
하고 사용하는 것과 동일합니다 a[$2, $4]
.
두 번째 솔루션은 다음을 사용합니다.큐
도구 q는 CSV 파일에 대해 데이터베이스와 유사한 쿼리를 수행하는 데 사용할 수 있습니다.
바라보다http://harelba.github.io/q/또는https://github.com/harelba/q
이 솔루션에는 다음과 같은 문제가 있습니다. 의 열 헤더가 비어 있습니다 B.txt
. 해결 방법으로 Empty
파일의 헤더 줄에 헤더를 추가했습니다.
그래서 저는 다음 파일을 사용합니다.
A.txt
Cycle Well Value Target
1 A1 5.07368111264623 EC
1 A1 3.06982862746599 FT
1 A1 2.46545646544623 EC
B.txt
Empty Well Fluor Target Content Sample
A1 Cy5 EC Unkn-01 2060563935
A1 Cy5 FT Unkn-09 2156515156
주문하다
q -H -t "select a.Cycle,a.Well,a.Value,a.Target,b.Content from A.txt as a inner join B.txt as b on a.Well=b.Well and a.Target=b.Target"
인쇄
1 A1 5.07368111264623 EC Unkn-01
1 A1 3.06982862746599 FT Unkn-09
1 A1 2.46545646544623 EC Unkn-01
제목을 인쇄하려면 printf
또는 echo
명령을 추가할 수 있습니다.
printf "Cycle\tWell\tValue\tTarget\tContent\n" > C.txt
q -H -t "select a.Cycle,a.Well,a.Value,a.Target,b.Content from A.txt as a inner join B.txt as b on a.Well=b.Well and a.Target=b.Target" >> C.txt
B.txt
사용할 수 있는 파일을 자동으로 수정하려면
printf "Empty" > B1.txt
cat B.txt >> B1.txt
printf "Cycle\tWell\tValue\tTarget\tContent\n" > C.txt
q -H -t "select a.Cycle,a.Well,a.Value,a.Target,b.Content from A.txt as a inner join B1.txt as b on a.Well=b.Well and a.Target=b.Target" >> C.txt
솔루션은 머리글 행의 명명된 열을 사용하여 일치하거나 인쇄할 열을 식별합니다.
답변2
2D 배열용 GNU가 있다고 가정하면 awk
다음 프로그램이 작업을 수행합니다.
awk -F'\t' 'NR==FNR&&FNR>1{map[$2][$4]=$5}\
NR>FNR{if (FNR==1) {$5="Content"} else {$5=map[$2][$4]}} NR>FNR' B.txt A.txt > C.txt
먼저 B.txt
특정 "웰" 및 "대상" 조합에 대한 "콘텐츠" 값의 매핑 생성을 처리합니다. 나중에 처리할 때 A.txt
( 로 표시됨 FNR
, 파일별 라인 카운터가 이제 NR
글로벌 라인 카운터보다 작음) 프로그램은 현재 라인에서 "Well"과 "Target"의 특정 조합을 찾고 해당 ""을 대체합니다. 이전에 생성된 지도 콘텐츠" 값입니다. 두 번째 파일을 처리한 후에만 출력을 인쇄합니다("stray" NR>FNR
경우).