各ファイルの最初の列に共通の文字列を含む行のみを含めるようにフィルタリングしたい24個のファイルがあります(例では、geneAとgeneFはColumn1の各ファイルに共通の唯一の文字列です)。出力には3つの列を維持する必要があります。ファイルはタブで区切られます。
私のファイルは次のとおりです。
ファイル1.txt
Column1 Column2 Column3
geneA 11 C
geneB 34 T
geneC 22 A
geneD 23 A
geneE 2 G
geneF 34 A
ファイル2.txt
Column1 Column2 Column3
geneA 34 A
geneF 67 G
geneG 77 A
geneZ 45 G
geneY 99 T
ファイル24.txt
Column1 Column2 Column3
geneA 22 A
geneF 7 T
geneL 34 C
geneK 66 A
geneM 34 T
geneP 47 G
私が望む出力は次のとおりです。
ファイル1.txt
Column1 Column2 Column3
geneA 11 C
geneF 34 A
ファイル2.txt
Column1 Column2 Column3
geneA 34 A
geneF 67 G
ファイル24.txt
Column1 Column2 Column3
geneA 22 A
geneF 7 T
ベストアンサー1
"내부" 편집을 위해 GNU awk를 사용하면 주어진 컬럼1 값이 입력 파일에 여러 번 나타날 수 있는 경우에도 작동합니다.
$ cat tst.awk
BEGIN {
for (fileNr=1; fileNr<ARGC; fileNr++) {
file = ARGV[fileNr]
delete thisFile
while ( (getline < file) > 0 ) {
thisFile[$1]
if ( fileNr == 1 ) {
common[$1]
}
}
close(file)
for ( val in common ) {
if ( !(val in thisFile) ) {
delete common[val]
}
}
}
}
(FNR == 1) || ($1 in common)
.
$ awk -i inplace -f tst.awk file{1..3}
$ tail -n +1 file{1..3}
==> file1 <==
Column1 Column2 Column3
geneA 11 C
geneF 34 A
==> file2 <==
Column1 Column2 Column3
geneA 34 A
geneF 67 G
==> file3 <==
Column1 Column2 Column3
geneA 22 A
geneF 7 T
그러나 column1 값이 각 파일에 한 번만 나타날 수 있는 경우에는 더 짧아질 수 있습니다.
$ awk -i inplace -v comm="$(cut -f1 file{1..3} | sort | uniq -c | awk '$1==3')" '
BEGIN{split(comm,tmp); for (i in tmp) common[tmp[i]]} (FNR == 1) || ($1 in common)
' file{1..3}
또는 내부 편집 기능이 있는 awk가 없는 경우:
$ comm="$(cut -f1 file{1..3} | sort | uniq -c | awk '$1==3')"
$ for file in file{1..3}; do
awk -v comm="$comm" '
BEGIN{split(comm,tmp); for (i in tmp) common[tmp[i]]} (FNR == 1) || ($1 in common)
' "$file" > tmp && mv tmp "$file"
done