나는 다음과 같은 상황에 처해 있습니다.
파일 1은 다음과 같습니다.
A
B
C
파일 2는 다음과 같습니다.
chr1 \t 1234523 \t A
chr3 \t 1234231 \t A
chr6 \t 121233 \t A
chr1 \t 1126685 \t B
chr1 \t 15834523 \t B
chr4 \t 12345647 \t C
chr12 \t 1456523 \t C
출력을 얻고 싶습니다.
A \t 3
B \t 2
C \t 2
난 내가 이걸 할 수 있다는 걸 알아
grep A File2 | wc -l
그러나 File1의 모든 행(700)에 대해 이 작업을 수행해야 합니다.
이를 어떻게 자동화할 수 있나요?
답변1
\t
s는 실제로 탭 문자이고 동일한 열에 발생하며 A는 AA가 아닌 A에만 일치한다고 가정합니다 . a
A, B, C를 포함하는 파일과 b
일치 여부를 계산하려는 파일(제공한 두 번째 파일)을 가정 합니다.
먼저, 가능한 일치 항목만 가져오고
b
나머지는 모두 무시해야 합니다. 이것은 파일의 일부를 잘라내는 데b
사용할 수 있는 세 번째 열입니다.cut
컷 -f 3b
그런 다음 이를 발생 횟수 및 발생 횟수 목록으로 변환해야 합니다.
uniq
출력을 정렬하고 이를 계산하는 데 사용할 수 있습니다.cut
정렬|유니클로-c
마지막으로, 당신은 이것을 위해모두in
b
이지만 의 값만 필요합니다a
.join
이를 사용하여 공통 필드(이 경우 첫 번째이자 유일한 필드a
(기본적으로 이 작업을 수행하는 것으로 보임)와 두 번째 파일(2
)b
인 두 번째 필드(-2
)) 에서 서로 다른 두 파일을 연결할 수 있습니다.연결-2 2a 결과-b
몇 가지 다른 방법으로 연결할 수 있으며, 한 가지 가능한 방법은 bash
프로세스 교체에서 명명된 파이프를 사용하는 것입니다.
join -2 2 a <(cut -f 3 b | sort | uniq -c)
이것은 b를 세 번만 처리하고(다른 열 sort
및 제거 uniq
) 조인이 입력을 정렬해야 하기 때문에 각 파일을 한 번만 읽을 것이기 때문에 grep 단독보다 적어도 더 나을 것입니다. 물론 이것은 내가 만든 가정에 의존합니다(그리고 정렬도 해야 a
하지만 이는 이전의 정렬되지 않은 경우를 <(sort a)
대체할 뿐입니다.a
답변2
예제 입력에서 탭으로 구분된 레코드의 마지막 필드에 있는 모든 고유 값을 계산하려고 합니다. 이 작업을 수행하는 awk 스니펫은 다음과 같습니다.
awk -F '\t' '
{++a[$NF]}
END {for (x in a) {print x "\t" a[x]}}
' File2
답변3
while 루프를 사용하여 이 작업을 수행할 수 있습니다.
while read arg < FILE1; do echo -n -e "$arg\t"; grep "$arg" FILE2 | wc -l; done
이는 FILE1을 읽고 각 행에 대해 for 루프는 문자열을 $arg 변수에 저장합니다.
그런 다음 $arg를 echo합니다(-n은 끝에 줄 반환(\n)을 삽입하지 않음을 의미하고, -e는 이스케이프 문자를 수행함을 의미합니다).
그런 다음 FILE2에서 발견된 $arg의 발생 횟수를 표시합니다.