我有两个文件,我想比较它们的1st columns
并将2nd column
的{{1}}附加到file2.txt
的末尾,除非存在匹配项:>
file1.txt
我正在尝试下面的代码-我希望它可以工作-:
file1.txt
NC_000008.10 1264 5646 G_synym=E4566
NC_000008.10 1264 5646 G=AGO2
NC_000008.10 5584 5646 G=AGO2
NC_000008.10 5218 5410 G=AGO2
NC_000008.10 2911 3031 G=AGO2
NC_000008.10 2552 2733 G=AGO2
NC_000008.10 0473 0609 G=AGO2
NC_000008.10 9494 9628 G=AGO2
NC_000008.10 8584 8671 G=AGO2
NC_000008.10 7188 7335 G=AGO2
file2.txt
NC_000001.10 chr1
NC_000002.11 chr2
NC_000003.11 chr3
NC_000004.11 chr4
NC_000005.9 chr5
NC_000006.11 chr6
NC_000007.13 chr7
NC_000008.10 chr8
NC_000009.11 chr9
NC_000010.10 chr1
给出以下输出:
awk 'NR==FNR { a[$1] = $0; next }($1) in a { print a[$1], $2 }' file1.txt file2.txt
它只是随机打印其中一项匹配项。
但是预期的输出将是:
NC_000008.10 7188 7335 G=AGO2 chr8
如何使NC_000008.10 1264 5646 G_synym=E4566 chr8
NC_000008.10 1264 5646 G=AGO2 chr8
NC_000008.10 5584 5646 G=AGO2 chr8
NC_000008.10 5218 5410 G=AGO2 chr8
NC_000008.10 2911 3031 G=AGO2 chr8
NC_000008.10 2552 2733 G=AGO2 chr8
NC_000008.10 0473 0609 G=AGO2 chr8
NC_000008.10 9494 9628 G=AGO2 chr8
NC_000008.10 8584 8671 G=AGO2 chr8
NC_000008.10 7188 7335 G=AGO2 chr8
打印所有匹配项而不是仅打印所有匹配项?
答案 0 :(得分:2)
您应该在Awk
中使用的代码已经
awk 'FNR == NR { hash[$1] = $2; next } $1 in hash { NF++; $NF = hash[$1] }1' file2 file1
想法是在file2
上,我们将第一列中的值与第二个中的值进行哈希运算。在遍历file1
时,为了匹配哈希索引中的值,我们引入了一个新列来存储哈希值。 NF++
基本上将文件中的列数增加一,因为我们引入了包含哈希值的新列。
要生成更格式化的命令输出,请将输出分隔符设置到选项卡OFS="\t"
或使用column命令,即,将awk
的结果传递给column -t
。
答案 1 :(得分:2)
如果文件在密钥中排序,最简单的是
$ join -a1 file1 file2 | column -t
NC_000008.10 1264 5646 G_synym=E4566 chr8
NC_000008.10 1264 5646 G=AGO2 chr8
NC_000008.10 5584 5646 G=AGO2 chr8
NC_000008.10 5218 5410 G=AGO2 chr8
NC_000008.10 2911 3031 G=AGO2 chr8
NC_000008.10 2552 2733 G=AGO2 chr8
NC_000008.10 0473 0609 G=AGO2 chr8
NC_000008.10 9494 9628 G=AGO2 chr8
NC_000008.10 8584 8671 G=AGO2 chr8
NC_000008.10 7188 7335 G=AGO2 chr8
column -t
仅用于精美格式。 a1
将打印第一个文件中不匹配的记录。
答案 2 :(得分:1)
请尝试以下操作:
const handlers = asHandlerMap({
"number/append": numberReducer,
"dog/walk": dogWalkReducer
}); // okay, handlers is of type HandlerMap<NumberAppendAction | DogWalkAction>
您应该先阅读file2,然后阅读file1。
但是,在您的问题中有些模棱两可,您没有说是否应该打印awk 'NR==FNR{a[$1]=$2;next}$1 in a{$(++NF)=a[$1]}1' file2.txt file1.txt
行。
如果您不希望这些行不匹配,那么:
not matched
另一件事是,输出字段用单个空格分隔。由于输入文件的格式似乎不错,因此您可能想awk 'NR==FNR{a[$1]=$2;next}$1 in a{$(++NF)=a[$1];print}' file2.txt file1.txt
用-v OFS="\t"
分隔输出。
请注意,如果file2可以为空,则应将TAB
更改为其他文件检查方法,例如GNU awk的NR==FNR
,ARGIND==1
或FILENAME=="file2.txt"
等。>
FILENAME==ARGV[1]
检查文件,这基本上是第一个读取文件(此处为NR==FNR
)。
file2.txt
是用于存储file1.txt第二行的数组,使用第一行作为键。
a
看看$1 in a
是否存在于数组$1
中作为键,如果存在则表示匹配。 (如果要改为检查该值,则可以更改为a
。当您确定该值不会为空时,可以互换使用它们。)
a[$1]
将字段号增加1。++NF
代表最后一列。所以
$NF
代表$(++NF)
最后一列之后的列。
最后裸露的file2.txt
只是一个简单的1
,暗示着true
块。