Linux 基于查找表的AWK字段替换

Linux 基于查找表的AWK字段替换,linux,awk,replace,Linux,Awk,Replace,我试图使用查找表替换file1第1列中的值。示例(选项卡分隔): 查找表: chr1 NC_000001.11 chr2 NC_000002.12 chr3 NC_000003.12 chr4 NC_000004.12 chr5 NC_000005.10 chr6 NC_000006.12 chr7 NC_000007.14 chr8 NC_000008.11 chr9 NC_000009.12 chr10 NC_000010.11 chr11 NC_000011.10 chr12 NC_0

我试图使用查找表替换file1第1列中的值。示例(选项卡分隔):

查找表:

chr1 NC_000001.11 
chr2 NC_000002.12 
chr3 NC_000003.12
chr4 NC_000004.12
chr5 NC_000005.10
chr6 NC_000006.12
chr7 NC_000007.14
chr8 NC_000008.11
chr9 NC_000009.12
chr10 NC_000010.11
chr11 NC_000011.10
chr12 NC_000012.12
chr13 NC_000013.11
chr14 NC_000014.9
chr15 NC_000015.10
chr16 NC_000016.10
chr17 NC_000017.11
chr18 NC_000018.10
chr19 NC_000019.10
chr20 NC_000020.11
chr21 NC_000021.9
chr22 NC_000022.11 
正在使用的脚本:

awk 'FNR==NR{a[$1]=$2;next} {for (i in a)sub(i,a[i]);print' lookup.txt file1 > new_table.txt
带注释的输出,哪一行正确/不正确(括号中有正确答案):

我不理解为什么它不工作的模式,并欢迎任何关于awk脚本的帮助。我原以为只有两位数,例如chr17,但chr21似乎工作正常

非常感谢,不是吗

awk 'FNR==NR{a[$1]=$2;next}{$1=a[$1]}1' lookup.txt file1
?

输出:

NC_000001.11 1243 A T 0.14
NC_000005.10 1432 G C 0.0006
NC_000010.11 731 T C 0.9421
NC_000011.10 98234 T G .000032
NC_000012.12 1284 A T 0.93428
NC_000017.11 941 G T 0.1111
NC_000019.10 134325 T C 0.00001
NC_000021.9 9824 T C 0.9
说明:

# true as long as we are reading the first file, lookup.txt
FNR==NR {
    # create a lookup array 'a' indexed by field 1 of lookup txt
    a[$1]=$2
    # don't process further actions
    next
}

# because of the 'next' statement above, this will be only executed
# when we are processing the second file, file1
{
    # translate field 1. use the value from the lookup array
    $1=a[$1]
}

# always true. print the line
1

PS:如果可能在查找表中找不到条目,您可以为它们使用特殊文本:

awk 'FNR==NR{a[$1]=$2;next}{$1=($1 in a)?a[$1]:"NOT FOUND "$1}1' lookup.txt file1
难道不是:

awk 'FNR==NR{a[$1]=$2;next}{$1=a[$1]}1' lookup.txt file1
?

输出:

NC_000001.11 1243 A T 0.14
NC_000005.10 1432 G C 0.0006
NC_000010.11 731 T C 0.9421
NC_000011.10 98234 T G .000032
NC_000012.12 1284 A T 0.93428
NC_000017.11 941 G T 0.1111
NC_000019.10 134325 T C 0.00001
NC_000021.9 9824 T C 0.9
说明:

# true as long as we are reading the first file, lookup.txt
FNR==NR {
    # create a lookup array 'a' indexed by field 1 of lookup txt
    a[$1]=$2
    # don't process further actions
    next
}

# because of the 'next' statement above, this will be only executed
# when we are processing the second file, file1
{
    # translate field 1. use the value from the lookup array
    $1=a[$1]
}

# always true. print the line
1

PS:如果可能在查找表中找不到条目,您可以为它们使用特殊文本:

awk 'FNR==NR{a[$1]=$2;next}{$1=($1 in a)?a[$1]:"NOT FOUND "$1}1' lookup.txt file1

我相信
sub
可能是OP尝试中的问题,没有彻底检查,这可以通过以下方式实现:

awk 'FNR==NR{arr[$1]=$2;next} ($1 in arr){first=$1;$1="";print arr[first],$0}' lookup_table Input_file


OP尝试的问题(仅为理解目的,不运行以获得显示的示例结果):尽管OP的代码显示一个看起来不像完整的代码,但它并不能找出根据OP的问题给出错误输出的原因,我已将其编写如下

awk'FNR==NR{a[$1]=$2;next}{for(i in a){line=$0;if(sub(i,a[i]){打印(前一行)行“>>>(数组键)“i”…(数组值)“a[i]”(新行)$0}}}}查找表输入文件

所以,每当一个适当的替换发生时,它只打印如下的行,在这里我们可以看到OP的代码出了什么问题

chr1 1243 A T 0.14 chr1 1243 A T 0.14 >>>(array key)chr1....(array value)NC_000001.11............(new line)NC_000001.11 1243 A T 0.14
chr5 1432 G C 0.0006chr5 1432 G C 0.0006>>>(array key)chr5....(array value)NC_000005.10............(new line)NC_000005.10 1432 G C 0.0006
chr10 731 T C 0.9421chr10 731 T C 0.9421>>>(array key)chr1....(array value)NC_000001.11............(new line)NC_000001.110 731 T C 0.9421
chr11 98234 T G .000032chr11 98234 T G .000032>>>(array key)chr1....(array value)NC_000001.11............(new line)NC_000001.111 98234 T G .000032
chr12 1284 A T 0.93428chr12 1284 A T 0.93428>>>(array key)chr12....(array value)NC_000012.12............(new line)NC_000012.12 1284 A T 0.93428
chr17 941 G T 0.1111chr17 941 G T 0.1111>>>(array key)chr1....(array value)NC_000001.11............(new line)NC_000001.117 941 G T 0.1111
chr19 134325 T C 0.00001chr19 134325 T C 0.00001>>>(array key)chr1....(array value)NC_000001.11............(new line)NC_000001.119 134325 T C 0.00001
chr21  9824 T C 0.9chr21  9824 T C 0.9>>>(array key)chr21....(array value)NC_000021.9............(new line)NC_000021.9  9824 T C 0.9
我们可以很容易看到的地方
chr1 1243 A T 0.14 chr1 1243 A T 0.14
NC_000001.11 1243 A T 0.14
这是因为数组键(chr1)会被数组值(NC_000001.11)替换,如果您为了理解而看到上面显示的输出。

我相信
sub
可能是OP尝试的问题,如果没有彻底检查,只需通过以下方式完成:

awk 'FNR==NR{arr[$1]=$2;next} ($1 in arr){first=$1;$1="";print arr[first],$0}' lookup_table Input_file


OP尝试的问题(仅为理解目的,不运行以获得显示的示例结果):尽管OP的代码显示一个看起来不像完整的代码,但它并不能找出根据OP的问题给出错误输出的原因,我已将其编写如下

awk'FNR==NR{a[$1]=$2;next}{for(i in a){line=$0;if(sub(i,a[i]){打印(前一行)行“>>>(数组键)“i”…(数组值)“a[i]”(新行)$0}}}}查找表输入文件

所以,每当一个适当的替换发生时,它只打印如下的行,在这里我们可以看到OP的代码出了什么问题

chr1 1243 A T 0.14 chr1 1243 A T 0.14 >>>(array key)chr1....(array value)NC_000001.11............(new line)NC_000001.11 1243 A T 0.14
chr5 1432 G C 0.0006chr5 1432 G C 0.0006>>>(array key)chr5....(array value)NC_000005.10............(new line)NC_000005.10 1432 G C 0.0006
chr10 731 T C 0.9421chr10 731 T C 0.9421>>>(array key)chr1....(array value)NC_000001.11............(new line)NC_000001.110 731 T C 0.9421
chr11 98234 T G .000032chr11 98234 T G .000032>>>(array key)chr1....(array value)NC_000001.11............(new line)NC_000001.111 98234 T G .000032
chr12 1284 A T 0.93428chr12 1284 A T 0.93428>>>(array key)chr12....(array value)NC_000012.12............(new line)NC_000012.12 1284 A T 0.93428
chr17 941 G T 0.1111chr17 941 G T 0.1111>>>(array key)chr1....(array value)NC_000001.11............(new line)NC_000001.117 941 G T 0.1111
chr19 134325 T C 0.00001chr19 134325 T C 0.00001>>>(array key)chr1....(array value)NC_000001.11............(new line)NC_000001.119 134325 T C 0.00001
chr21  9824 T C 0.9chr21  9824 T C 0.9>>>(array key)chr21....(array value)NC_000021.9............(new line)NC_000021.9  9824 T C 0.9
我们可以很容易看到的地方
chr1 1243 A T 0.14 chr1 1243 A T 0.14
NC_000001.11 1243 A T 0.14
这是因为数组键(chr1)被数组值(NC_000001.11)替换如果您看到上面显示的输出以便于理解。

看起来是sub导致了问题,因此只需在行中加上空格将$1指定的索引值前置,然后用缩写1打印该行即可:

awk 'FNR==NR{a[$1]=$2;next} {$0=a[$1]" "$0 }1' lookup.txt file1 > new_table.txt

看起来是sub导致了问题,因此只需在$1指定的索引的值前面加一个空格,然后用缩写1打印该行,这样:

awk 'FNR==NR{a[$1]=$2;next} {$0=a[$1]" "$0 }1' lookup.txt file1 > new_table.txt

由于所显示的示例文件中根本没有NC_000005.101432
,请更正您的示例。请更正您问题中输入和预期输出的示例,然后让我们知道。您是否有一个或两个文件中的DOS回车?编辑@RavinderSingh13感谢现场@我不这么认为。这些文件仅来自linux,我已使用列-t函数将它们重新格式化为制表符分隔。请更正您的示例,因为
NC_000005.101432
根本不在您显示的示例文件中,请更正您问题中输入和预期输出的样本,然后让我们知道。您是否在一个或两个文件中都有DOS回车?编辑@RavinderSingh13感谢现场@我不这么认为。这些文件仅来自linux,我已使用column-t函数将它们重新格式化为制表符分隔。需要修改整个记录吗?
$0
?我们正在为每行打印$0,并在语句末尾使用缩写“1”。但这不是我的问题。为什么不仅仅是
$1=a[$1]
?因为我们不是用[$1]替换$1,而是先用[$1]替换$1,然后再加上空格。我猜另一个是做$1=a[$1]“”“$1需要修改整个记录吗
$0
?我们正在为每行打印$0,并在语句末尾使用缩写“1”。但这不是我的问题。为什么不仅仅是
$1=a[$1]
?因为我们不是用[$1]替换$1,而是先用[$1]替换$1,然后再加上空格。我猜另一个是做$1=a[$1]“”$1