Сбой команды awk с подстановкой команды

Выполнение этой команды завершается неудачно:

$(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} удалены. Почему эти одинарные кавычки нарушают подстановку команд?

редактировать: изменил backtick на $(...) нотации. Также добавлено решение, которое я не понимаю.

2 ответа

Решение

Попробуйте удалить кавычки из создаваемой команды.

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

Для объяснения см. Принятый ответ в Почему замена команды меняет работу аргументов в кавычках?

Похоже, вы пытаетесь взять кучу уникальных 2-х полей из файла, начиная со строки 2, и сопоставить их с числами на основе их алфавитного порядка, а затем применить изменения к тому же файлу. Если так, то с GNU awk для sorted_in и редактирования на месте это будет:

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

Если это не то, что вам нужно, отредактируйте ваш вопрос, чтобы показать краткий, тестируемый пример ввода и ожидаемый результат.

Другие вопросы по тегам