awk命令因命令替换而失败

时间:2017-07-05 15:49:37

标签: bash awk command-substitution

运行此命令失败:

$(printf "awk '{%sprint}'" $(tail -n +2 file.txt | cut -f2 | sort | uniq | awk 'BEGIN{a=1}{printf "gsub(\"%s\",%i);", $1,a++}')) file.txt

它出现以下错误:

awk: '
awk: ^ invalid char ''' in expression

但是,如果我运行替换命令,我会得到:

awk '{gsub("ACB",1);gsub("ASW",2);gsub("BEB",3);gsub("CDX",4);gsub("CEU",5);gsub("CHB",6);gsub("CHS",7);gsub("CLM",8);gsub("ESN",9);gsub("FIN",10);gsub("GBR",11);gsub("GIH",12);gsub("GWD",13);gsub("IBS",14);gsub("ITU",15);gsub("JPT",16);gsub("KHV",17);gsub("LWK",18);gsub("MSL",19);gsub("MXL",20);gsub("PEL",21);gsub("PJL",22);gsub("PUR",23);gsub("STU",24);gsub("TSI",25);gsub("YRI",26);print}'

我可以这样运行:

awk '{gsub("ACB",1);gsub("ASW",2);gsub("BEB",3);gsub("CDX",4);gsub("CEU",5);gsub("CHB",6);gsub("CHS",7);gsub("CLM",8);gsub("ESN",9);gsub("FIN",10);gsub("GBR",11);gsub("GIH",12);gsub("GWD",13);gsub("IBS",14);gsub("ITU",15);gsub("JPT",16);gsub("KHV",17);gsub("LWK",18);gsub("MSL",19);gsub("MXL",20);gsub("PEL",21);gsub("PJL",22);gsub("PUR",23);gsub("STU",24);gsub("TSI",25);gsub("YRI",26);print}' file.txt

它完美无缺。我做错了什么?

@ChrisLear给了我一个有效的解决方案,但我仍然不太明白命令解决方案在做什么。这是工作代码:

$(printf "awk {%sprint}" $(tail -n +2 file.txt | cut -f2 | sort | uniq | awk 'BEGIN{a=1}{printf "gsub(\"%s\",%i);", $1,a++}')) file.txt

{%sprint}周围的单引号将被删除。为什么这些单引号会破坏命令替换?

编辑:将反引号更改为$(...)表示法。还添加了我不明白的解决方案。

2 个答案:

答案 0 :(得分:1)

尝试从正在生成的命令中删除引号。

`printf "awk {%sprint}" $(tail -n +2 file.txt | cut -f2 | sort | uniq | awk 'BEGIN{a=1}{printf "gsub(\"%s\",%i);", $1,a++}')` file.txt

有关说明,请参阅Why does command substitution change how quoted arguments work?

上接受的答案

答案 1 :(得分:0)

看起来您正试图从第2行开始的文件中获取一堆独特的第二个字段,并根据字母顺序将这些字段映射到数字,然后将更改应用于同一文件。如果是这样,那么使用GNU awk进行sorted_in和inplace编辑,即:

awk -i inplace '
NR==FNR {
    if (NR>1) {
        map[$2]
    }
    next
}
FNR==1 {
    PROCINFO["sorted_in"] = "@ind_str_asc"
    for (str in map) {
        map[str] = ++i
    }
}
{
    $2 = map[$2]
    print
}
' file.txt

如果那不是您需要的,那么编辑您的问题以显示简洁,可测试的样本输入和预期输出。