使用 awk/sed/join 映射制表符分隔文件和列表
Map tab separated file with a list using awk/sed/join
我有多个包含两列(制表符分隔)的大文件。
这些文件的内容是这样的:
working_file-1
K00001 0.188
K00005 15.97
K00008 188.09
映射文件
K00001
K00002
K00003
K00004
K00005
K00006
K00007
K00008
映射文件范围为K00001 - K25804
我想将我的 working_file-1 映射到映射文件,以便输出如下所示:
K00001 0.188
K00002
K00003
k00004
K00005 15.97
K00006
K00007
k00008 188.09
空格(working_file 中不存在 K0)可以用零填充(如果可能)或留空。
到目前为止,我通过关注其他类似的帖子尝试了这些代码(但没有成功):
awk 'NR==FNR {a[]++; next} in a' mapping file working_file-1 > output.file
grep -Fw -f mapping file working_file-1 > output.file
编辑:od -c work1 的输出; od -c 地图
0000000 K 0 0 0 0 1 \r \n K 0 0 0 0 2 \r \n
0000020 K 0 0 0 0 3 \r \n K 0 0 0 0 4 \r \n
0000040 K 0 0 0 0 5 \r \n K 0 0 0 0 6 \r \n
0000060 K 0 0 0 0 7 \r \n K 0 0 0 0 8 \r \n
将 GNU sort
用于 -s
(稳定排序)这可能是您想要的:
$ sort -k1,1 -u -s working_file-1 mapping_file
K00001 0.188
K00002
K00003
K00004
K00005 15.97
K00006
K00007
K00008 188.09
或者如果你想添加 0
s:
$ sort -k1,1 -u -s working_file-1 mapping_file |
awk -v OFS='\t' '{print , +=0}'
K00001 0.188
K00002 0
K00003 0
K00004 0
K00005 15.97
K00006 0
K00007 0
K00008 188.09
如果您没有 GNU 排序,那么您可以这样做:
$ sort -k1,1 -k2,2rn working_file-1 mapping_file |
awk -v OFS='\t' ' != p{print , +0; p=}'
K00001 0.188
K00002 0
K00003 0
K00004 0
K00005 15.97
K00006 0
K00007 0
K00008 188.09
给定一个“地图”文件,例如:
a
b
c
d
e
f
g
h
和一个“work1”文件,如:
a A
c C
g G
和所需的“merged1”输出如:
a A
b
c C
d
e
f
g G
h
然后join
可以进行合并:
join -1 1 -2 1 -a 1 -o 0,2.2 map work1 > merged1
-1 1 -2 1
在每个文件的第一个(space 分隔)字段加入
-a 1
从第一个文件打印行,即使未配对
-o 0,2.2
将输出格式化为连接字段(第一列)、分隔符(space),然后是第二个文件的第二个字段
改为生成“merged2”,如:
a A
b 0
c C
d 0
e 0
f 0
g G
h 0
添加-e
选项:
join -1 1 -2 1 -a 1 -e 0 -o 0,2.2 map work1 > merged2
如果“work2”的字段由单个 space 以外的字符分隔,请使用 -t
选项。
例如,“work2”使用单个制表符分隔符,例如:
a A
c C
g G
(注意:Whosebug 使用 spaces 而不是单个选项卡显示它)然后使用 POSIX shell,使用 -t ' '
(即 QUOTE TAB QUOTE - 可能需要输入为:'CTRL-VTAB' if shell 执行历史补全):
join -t ' ' -1 1 -2 1 -a 1 -e 0 -o 0,2.2 map work2 >merged3
或使用 bash,使用 -t $'\t'
是可能的:
join -t $'\t' -1 1 -2 1 -a 1 -e 0 -o 0,2.2 map work2 >merged3
生成“merged3”,如:
a A
b 0
c C
d 0
e 0
f 0
g G
h 0
(注意:Whosebug 再次将选项卡显示为 spaces)
我有多个包含两列(制表符分隔)的大文件。 这些文件的内容是这样的:
working_file-1
K00001 0.188
K00005 15.97
K00008 188.09
映射文件
K00001
K00002
K00003
K00004
K00005
K00006
K00007
K00008
映射文件范围为K00001 - K25804
我想将我的 working_file-1 映射到映射文件,以便输出如下所示:
K00001 0.188
K00002
K00003
k00004
K00005 15.97
K00006
K00007
k00008 188.09
空格(working_file 中不存在 K0)可以用零填充(如果可能)或留空。
到目前为止,我通过关注其他类似的帖子尝试了这些代码(但没有成功):
awk 'NR==FNR {a[]++; next} in a' mapping file working_file-1 > output.file
grep -Fw -f mapping file working_file-1 > output.file
编辑:od -c work1 的输出; od -c 地图
0000000 K 0 0 0 0 1 \r \n K 0 0 0 0 2 \r \n
0000020 K 0 0 0 0 3 \r \n K 0 0 0 0 4 \r \n
0000040 K 0 0 0 0 5 \r \n K 0 0 0 0 6 \r \n
0000060 K 0 0 0 0 7 \r \n K 0 0 0 0 8 \r \n
将 GNU sort
用于 -s
(稳定排序)这可能是您想要的:
$ sort -k1,1 -u -s working_file-1 mapping_file
K00001 0.188
K00002
K00003
K00004
K00005 15.97
K00006
K00007
K00008 188.09
或者如果你想添加 0
s:
$ sort -k1,1 -u -s working_file-1 mapping_file |
awk -v OFS='\t' '{print , +=0}'
K00001 0.188
K00002 0
K00003 0
K00004 0
K00005 15.97
K00006 0
K00007 0
K00008 188.09
如果您没有 GNU 排序,那么您可以这样做:
$ sort -k1,1 -k2,2rn working_file-1 mapping_file |
awk -v OFS='\t' ' != p{print , +0; p=}'
K00001 0.188
K00002 0
K00003 0
K00004 0
K00005 15.97
K00006 0
K00007 0
K00008 188.09
给定一个“地图”文件,例如:
a
b
c
d
e
f
g
h
和一个“work1”文件,如:
a A
c C
g G
和所需的“merged1”输出如:
a A
b
c C
d
e
f
g G
h
然后join
可以进行合并:
join -1 1 -2 1 -a 1 -o 0,2.2 map work1 > merged1
-1 1 -2 1
在每个文件的第一个(space 分隔)字段加入-a 1
从第一个文件打印行,即使未配对-o 0,2.2
将输出格式化为连接字段(第一列)、分隔符(space),然后是第二个文件的第二个字段
改为生成“merged2”,如:
a A
b 0
c C
d 0
e 0
f 0
g G
h 0
添加-e
选项:
join -1 1 -2 1 -a 1 -e 0 -o 0,2.2 map work1 > merged2
如果“work2”的字段由单个 space 以外的字符分隔,请使用 -t
选项。
例如,“work2”使用单个制表符分隔符,例如:
a A
c C
g G
(注意:Whosebug 使用 spaces 而不是单个选项卡显示它)然后使用 POSIX shell,使用 -t ' '
(即 QUOTE TAB QUOTE - 可能需要输入为:'CTRL-VTAB' if shell 执行历史补全):
join -t ' ' -1 1 -2 1 -a 1 -e 0 -o 0,2.2 map work2 >merged3
或使用 bash,使用 -t $'\t'
是可能的:
join -t $'\t' -1 1 -2 1 -a 1 -e 0 -o 0,2.2 map work2 >merged3
生成“merged3”,如:
a A
b 0
c C
d 0
e 0
f 0
g G
h 0
(注意:Whosebug 再次将选项卡显示为 spaces)