I have two tab separated files (FileA.tsv and FileB.tsv).
FileA.tsv
id | graph | circle | several columns... | length |
---|---|---|---|---|
196-0 | 196 | 0 | ---- | 12874 |
195-1 | 195 | 1 | ---- | 12874 |
56-0 | 56 | 0 | ---- | 3349 |
115-1 | 115 | 1 | ---- | 5297 |
File A has hundreds of lines and 12 columns, not all depicted here. Each value of 2 and 3 is not unique, but their specific combination is. As such, event_id is an unique identifier, made of the values in 2 and 3 concatenated.
FileB.tsv
Column 1 | Column 2 | Column 3 | several columns... | Column 16 |
---|---|---|---|---|
195 | 1 | coverage | ---- | CTTGCTTGAGCTGCTCTGCAA... |
196 | 0 | coverage | ---- | TTCTAAAGTATAAAGCCTGTC... |
196 | 9 | coverage | --- | TTCTAAAGTATAAAGCCTGTC ... |
196 | 11 | coverage | --- | ACATTTAAAGAATTGCTTAAG... |
FileB does not have headers.
Columns 2 and 3 match some of the columns 1 and 2 of file A. Once again the values in columns 1 and 2 are not unique but their specific combination is. All the rows appearing in FileB always have matches in FileA, but the opposite is not true.
Using awk, I would like to check if each row of FileA has $2 and $3 matching $1 and $2 of FileB, and if so,print the full FileA row and add the corresponding $16 value of FIleB to the end of that row. If not, print the FIleA row as it is.
Expected Output (FileC):
id | graph | circle | several columns | length | Column 16 |
---|---|---|---|---|---|
196-0 | 196 | 0 | ---- | 12874 | TTCTAAAGTATAAAGCCTGTC... |
195-1 | 195 | 1 | ---- | 12874 | CTTGCTTGAGCTGCTCTGCAA... |
56-0 | 56 | 0 | ---- | 3349 | ---- |
115-1 | 115 | 1 | ---- | 5297 | ---- |
So far, I have:
awk -F "\t" 'NR==FNR {a[$1,$2]=($16); next} ($2,$3) in a {print $0, a[$16]}' FileB.tsv FileA.tsv > FileC.tsv
This code does give me only the matched rows, however, it does not append $16 to the end of the matching rows:
Empty | Empty | Empty | Empty | Empty |
---|---|---|---|---|
196-0 | 196 | 0 | ---- | 12874 |
195-1 | 195 | 1 | ---- | 12874 |
If I try adding the If-Else statement:
awk -F "\t" 'NR==FNR {a[$1,$2]=($16); next} { if (($2,$3) in a) {print $0, a[$16]} else {print $0}}' FileB.tsv FileA.tsv > FileC.tsv
So as to keep the headers and non-matching rows of FileA, the output is simply FileA.
I'm new to awk, however I have researched a lot and found many examples of manipulation similar to this being done, and my code seems very similar to other examples I've seen.
However, I have yet to find an example in which there are two corresponding key rows between files, they are not in the same position AND the non-matching columns are also kept.
This is being run on several directories, each with their own set of FileA and FileB, using a Bash loop. No problems in that regard, all directories have their own outputting FileC, however wrong its contents may be:
set -euo pipefail
IFS=$'\n\t'
for D in ~/Path/to/directories/with/tables/*; do
if [ -d "${D}" ]; then
cd "$D"
awk -F "\t" 'NR==FNR {a[$1,$2]=($16); next} { if (($2,$3) in a) {print $0, a[$16]} else {print $0}}' *_FileB.tsv *_FileA.tsv > "${D}".FileC.tsv
fi
done ```
Any help or correction will be greatly appreciated.