안녕하세요. 테이블 파일이 있습니다(구분 기호 = \t
) A.txt
.
205 toto patho
207 tata benign
208 titi likely_patho
그리고 B.txt
:
210 lolo patho
211 lala benign
212 lili benign
세 번째 열이 "patho" 또는 "likely_patho"인 경우 두 번째 열의 값을 인쇄하는 파일이 필요합니다. 이 예를 통해 다음을 얻을 수 있습니다.
A toto;titi
B lolo
이를 위해 나는 다음을 수행했습니다.
for bla in *.txt; do
r="$(basename -s ".txt" $bla)"
awk -v filename=$r '($3=="patho" || $3=="likely_patho") {print filename"\t"$2}' $bla >> result.txt ;
done
그러나 파일에 여러 일치 항목(예 A.txt
: )이 포함된 경우 이 코드는 각 일치 항목에 대해 한 줄을 제공합니다.
A toto
A titi
B lolo
어떻게 하면 올바른 출력을 얻을 수 있나요? 감사해요
답변1
awk를 사용하십시오.
$ cat tst.awk
BEGIN {
split(t,tmp)
for ( i in tmp ) {
tgts[tmp[i]]
}
FS = OFS = "\t"
}
FNR == 1 {
fname = FILENAME
sub(/\.[^.]*$/,"",fname)
}
$3 in tgts {
hits[fname] = (fname in hits ? hits[fname] ";" : "") $2
}
END {
for ( fname in hits ) {
print fname, hits[fname]
}
}
$ awk -v t='patho likely_patho' -f tst.awk *.txt
A toto;titi
B lolo
답변2
노력하다:
awk ' FNR==1 { f=FILENAME;
sub(/\.[^.]*$/,"",f);
printf "%s%s\t",aline,f;
aline="\n";
s=""
}
($3=="patho" || $3=="likely_patho"){
printf "%s%s",s,$2;
s="; "
}
END{print ""}
' ./*.txt
답변3
시도해 보세요(한 줄이면 됩니다).
awk -v filename="$r" 'BEGIN { string=filename "\t" }
($3=="patho" || $3=="likely_patho") {printf string $2; string=";" }
END { printf "\n" } ' $bla >> result.txt ;
나는 string
접두사로 사용하고 파일 이름을 먼저 인쇄한 다음 세미콜론을 인쇄합니다.
마지막 개행 문자를 추가해야 합니다.
답변4
Perl 사용(가독성을 위해 추가 줄바꿈 사용):
$ perl -MFile::Basename -F'\t' -le '
$f = fileparse($ARGV, qw(.txt)) if $. == 1;
if ($F[2] =~ /^(likely_)?patho$/) {
push @{ $files{$f} }, $F[1]
};
close(ARGV) if eof; # close each input file and reset the line counter $. at eof
END {
foreach (sort keys %files) {
print "$_\t", join(";",@{ $files{$_} })
}
}' A.txt B.txt
A toto;titi
B lolo
-MFile::Basename
Perl에게 로드하라고 지시파일::기본 이름기준 치수. 이것은 Perl에 포함된 핵심 Perl 모듈입니다.-F
필드 구분 기호(탭)를 설정하고 Perl의-a
자동 분할 모드(각 입력 행을 awk와 유사하게 명명된 배열로 분할@F
)와-n
입력을 반복하는 Perl의 옵션(sed -n
및 처럼 작동awk
)도 활성화합니다.-l
줄 끝 자동 처리를 활성화합니다(\n
기본값). 즉, 각 입력 줄의 끝에서 개행 문자를 제거하고(Perl의chomp()
함수를 사용하여) 이를 각 명령문의 끝에 추가합니다print
.모든 Perl 명령줄 옵션은 에 설명되어 있습니다
man perlrun
.
스크립트는 각 입력 줄을 반복하고 세 번째 필드에서 일치하는 항목을 찾을 때마다( $F[2]
-perl 배열 인덱스는 0에서 시작) 두 번째 필드를 (HoA) middle 이라는 배열 해시에 추가합니다 %files
. 이는 키가 기본 파일 이름이고 값이 두 번째 필드의 문자열 배열인 해시(연관 배열)입니다. Perl 데이터 구조에 대한 자세한 내용은 perldata
, 및 perllol
의 매뉴얼 페이지를 참조하십시오.perldsc
모든 입력을 읽고 처리한 후에는 요청된 형식으로 파일 이름별로 정렬된 데이터를 출력합니다.
참고: ... if $. == 1;
이 close(ARGV) if eof
줄과 함께 각 새 파일의 첫 번째 줄에서 기본 파일 이름만 추출되는지 확인하십시오. 이것은 필수는 아니며 매우 큰 입력 파일이 있는 경우에만 유용할 작은 최적화입니다. 약간 더 짧은 행을 선호하거나 성능이 문제가 되지 않는 경우 close(ARGV) ...
행과 if $. == 1
조건을 제거하세요.