다음과 비슷한 파일이 4개 있습니다.
file A
>TCONS_00000867
>TCONS_00001442
>TCONS_00001447
>TCONS_00001528
>TCONS_00001529
>TCONS_00001668
>TCONS_00001921
file b
>TCONS_00001528
>TCONS_00001529
>TCONS_00001668
>TCONS_00001921
>TCONS_00001922
>TCONS_00001924
file c
>TCONS_00001529
>TCONS_00001668
>TCONS_00001921
>TCONS_00001922
>TCONS_00001924
>TCONS_00001956
>TCONS_00002048
file d
>TCONS_00001922
>TCONS_00001924
>TCONS_00001956
>TCONS_00002048
모든 파일에는 2000개 이상의 행이 포함되어 있으며 첫 번째 열을 기준으로 정렬됩니다.
모든 파일에서 공통점을 찾고 싶습니다. awk, grep 및 comm을 시도했지만 작동하지 않습니다.
답변1
파일이 이미 정렬되어 있으므로:
comm -12 a b |
comm -12 - c |
comm -12 - d
comm
파일 사이의 줄을 찾습니다 comm
. 기본적으로 comm
탭으로 구분된 3개의 열을 인쇄합니다.
- 첫 번째 파일에 고유한 줄,
- 두 번째 파일에 고유한 줄,
- 두 파일에 공통되는 줄입니다.
-1
, -2
, 옵션을 사용하면 -3
해당 열을 억제합니다. 따라서 보고서 및 comm -12 a b
공개 행. stdin을 나타내기 위해 파일 이름 대신 사용할 수 있습니다.a
b
-
답변2
cat a b c d |sort |uniq -c |sed -n -e 's/^ *4 \(.*\)/\1/p'
답변3
comm
입력으로 3개 이상의 파일이 필요하다면 좋을 것입니다. 그렇지 않기 때문에 값이 표시되지 않으며 다음을 사용하는 것이 좋습니다 grep
.
- 사전 정렬된 입력이 필요하지 않습니다.
- 출력 열을 억제할 필요가 없습니다.
- 명령어는 이렇게 짧고 간단합니다
comm
grep -f a.txt b.txt |
grep -f - c.txt |
grep -f - d.txt
-f <file>
grep에게 패턴을 찾도록 지시하여 에서 발견된 모든 행이 <file>
일치 항목으로 출력되도록 합니다. 이는 파이프 아래로 계속되므로 AND에 있는 줄은 일치하는 패턴으로 사용됩니다. 파이프 끝에 표시되는 유일한 출력은 각 파일에 나타나는 줄입니다.a.txt
b.txt
a.txt
b.txt
c.txt
답변4
사용행복하다(이전 Perl_6)
~$ raku -e 'my %h; for dir(test => / file \w /) { \
%h{$_}++ for .lines.unique }; \
.put if .value == 4 for %h;'
#OR
~$ raku -e 'my %h; my @a = dir(test => / file \w /); \
for @a { %h{$_}++ for .lines.unique }; \
for %h { .put if .value == @a.elems };'
위 내용은 Perl 계열의 프로그래밍 언어인 Raku로 작성된 답변입니다. 간단히 말해서 Raku의 dir
기능은 로컬 디렉터리를 확인하고 파일 이름과 일치하는 정규식을 추출하는 데 사용됩니다. 여기서는 파일 이름 뒤에 단어 문자가 붙는다고 가정 하지만 file
파일을 적절한 정규식(와일드카드 패턴이 아님)과 \w
일치시키는 것도 쉽습니다 .\.txt
위의 두 답변 모두 %h
해시 값이 선언되었습니다. 파일 이름(실제로 .IO
는 객체) 을 얻으면 line
신중하게 반복하여 for
동일한 줄을 볼 때마다 해시 키를 증가시킵니다.
value
첫 번째 답변(마지막 문)에서 일치 항목이 있으면 4
4개의 입력 파일 모두에서 행이 반환됩니다. 두 번째 답변(마지막 문)에서 value
일치하는 항목 @a.elems
, 즉 입력 파일 수(즉, 값이 동적으로 설정됨)가 있는 경우 해당 행이 반환됩니다.
입력 예(참고: 파일 이름은 fileA
, fileB
등입니다. 또한 fileA
OP의 첫 번째 파일과 비교하여 끝에 추가 줄이 있습니다):
fileA
>TCONS_00000867
>TCONS_00001442
>TCONS_00001447
>TCONS_00001528
>TCONS_00001529
>TCONS_00001668
>TCONS_00001921
>TCONS_00001922
fileB
>TCONS_00001528
>TCONS_00001529
>TCONS_00001668
>TCONS_00001921
>TCONS_00001922
>TCONS_00001924
fileC
>TCONS_00001529
>TCONS_00001668
>TCONS_00001921
>TCONS_00001922
>TCONS_00001924
>TCONS_00001956
>TCONS_00002048
fileD
>TCONS_00001922
>TCONS_00001924
>TCONS_00001956
>TCONS_00002048
출력 예(모든 키/값 개수 표시):
~$ raku -e 'my %h; for dir(test => / file \w /) { %h{$_}++ for .lines.unique }; .say for %h.sort: -*.value;'
>TCONS_00001922 => 4
>TCONS_00001668 => 3
>TCONS_00001921 => 3
>TCONS_00001924 => 3
>TCONS_00001529 => 3
>TCONS_00002048 => 2
>TCONS_00001528 => 2
>TCONS_00001956 => 2
>TCONS_00000867 => 1
>TCONS_00001442 => 1
>TCONS_00001447 => 1
출력 예( .value == 4
또는 행만 표시 .value == @a.elems
):
~$ raku -e 'my %h; my @a = dir(test => / file \w /); for @a { %h{$_}++ for .lines.unique }; for %h { .key.put if .value == @a.elems};'
>TCONS_00001922
마지막으로 쉘 와일드카드를 선호하는 사람들을 위해 Raku도 이 작업을 수행할 수 있습니다. 중요한 점은 입력을 올바르게 읽으 $*ARGFILES
려면 동적 변수를 변환해야 한다는 점을 기억하는 것입니다..handles
~$ raku -e 'my ($n,%h); for $*ARGFILES.handles -> $fh { $n++; %h{$_}++ for $fh.lines.unique }; for %h { .key.put if .value == $n };' file?
>TCONS_00001922
참고: OP의 테스트 입력은 네 개의 파일 사이에 공통 줄이 없기 때문에 까다로운 것 같습니다! 따라서 첫 번째 파일( fileA
)은 양성 대조군을 제공하도록 수정되었습니다: >TCONS_00001922
.
https://stackoverflow.com/a/68774047/7270649
https://docs.raku.org/routine/dir
https://docs.raku.org
https://raku.org