KJ_*_*KJ_ 7 unix bash awk sed large-data
我试图替换大空格分隔的文本文件中的值,但无法找到适合此特定问题的答案:
假设我有一个文件"OLD_FILE",包含一个标题和大约200万行:
COL1 COL2 COL3 COL4 COL5
rs10 7 92221824 C A
rs1000000 12 125456933 G A
rs10000010 4 21227772 T C
rs10000012 4 1347325 G C
rs10000013 4 36901464 C A
rs10000017 4 84997149 T C
rs1000002 3 185118462 T C
rs10000023 4 95952929 T G
...
Run Code Online (Sandbox Code Playgroud)
我想使用大(2.8M行)转换表将每行的第一个值替换为相应的值.在此转换表中,第一列列出了我想要替换的值,第二列列出了相应的新值:
COL1_b36 COL2_b37
rs10 7_92383888
rs1000000 12_126890980
rs10000010 4_21618674
rs10000012 4_1357325
rs10000013 4_37225069
rs10000017 4_84778125
rs1000002 3_183635768
rs10000023 4_95733906
...
Run Code Online (Sandbox Code Playgroud)
所需的输出将是一个文件,其中第一列中的所有值都已根据转换表进行了更改:
COL1 COL2 COL3 COL4 COL5
7_92383888 7 92221824 C A
12_126890980 12 125456933 G A
4_21618674 4 21227772 T C
4_1357325 4 1347325 G C
4_37225069 4 36901464 C A
4_84778125 4 84997149 T C
3_183635768 3 185118462 T C
4_95733906 4 95952929 T G
...
Run Code Online (Sandbox Code Playgroud)
附加信息:
性能是一个问题(以下命令大约需要一年时间:
读ab; 做sed -i"s /\b $ a\b/$ b/g"OLD_FILE; 完成<CONVERSION_TABLE
很感谢任何形式的帮助.
Ste*_*eve 13
这是使用的一种方式awk:
awk 'NR==1 { next } FNR==NR { a[$1]=$2; next } $1 in a { $1=a[$1] }1' TABLE OLD_FILE
Run Code Online (Sandbox Code Playgroud)
结果:
COL1 COL2 COL3 COL4 COL5
7_92383888 7 92221824 C A
12_126890980 12 125456933 G A
4_21618674 4 21227772 T C
4_1357325 4 1347325 G C
4_37225069 4 36901464 C A
4_84778125 4 84997149 T C
3_183635768 3 185118462 T C
4_95733906 4 95952929 T G
Run Code Online (Sandbox Code Playgroud)
说明,按出现顺序:
NR==1 { next } # simply skip processing the first line (header) of
# the first file in the arguments list (TABLE)
FNR==NR { ... } # This is a construct that only returns true for the
# first file in the arguments list (TABLE)
a[$1]=$2 # So when we loop through the TABLE file, we add the
# column one to an associative array, and we assign
# this key the value of column two
next # This simply skips processing the remainder of the
# code by forcing awk to read the next line of input
$1 in a { ... } # Now when awk has finished processing the TABLE file,
# it will begin reading the second file in the
# arguments list which is OLD_FILE. So this construct
# is a condition that returns true literally if column
# one exists in the array
$1=a[$1] # re-assign column one's value to be the value held
# in the array
1 # The 1 on the end simply enables default printing. It
# would be like saying: $1 in a { $1=a[$1]; print $0 }'
Run Code Online (Sandbox Code Playgroud)