Циклические строки и столбцы внутри awk для подсчета определенной подстроки для каждой ячейки

Внутри одинарных кавычек ничего не раскрывается. Поэтому вам нужно выйти из одинарных кавычек. В любом случае вам нужно двойные -кавычки расширений ваших переменных, если только вы не хотите, чтобы к ним применялся split+glob, поэтому:

A=$(multichain-cli issue '{"name":'"$ASSET"',"open":true}' "$D")
#                         ''''''''  """"""  '''''''''''''
printf '%s\n' "$A"

('''', """"", чтобы показать, какие части в одинарных -кавычках, а какие в двойных -кавычках ).

Скорее всего, вы захотите, чтобы содержимое $ASSETбыло заключено в двойные кавычки в коде JSON, поэтому вам нужно включить их (в литерал, то есть в одинарные кавычки):

A=$(multichain-cli issue '{"name":"'"$ASSET"'","open":true}' "$D")
#                         '''''''''  """"""  ''''''''''''''

Не путайте двойные -кавычки, которые используются для цитирования оболочки (здесь, чтобы предотвратить разделение + подстановку при расширении $ASSET), и двойные -кавычки, которые дословно передаются в multichain-cli.

Возможно, вам придется рассмотреть случаи, когда $ASSETсодержит двойные кавычки или другие символы (, такие как обратная косая черта, новая строка или другие управляющие символы ), которые являются особыми в синтаксисе JSON. Для символов, отличных от -ASCII, вам также необходимо убедиться, что они закодированы так, как ожидается multichain-cli.

Кроме того, вы можете использовать двойные -кавычки оболочки для всего, например, @Bex показал , хотя это означает, что вам нужно экранировать "s (, но также и $,\и`)с обратной косой чертой в тексте, переданном в multichain-cli(, и избегайте использования древнего синтаксиса `...`для подстановки команд, поскольку он выполняет дополнительную обработку с обратной косой чертой ).

1
13.11.2019, 00:19
1 ответ

Причина, по которой это не работает, заключается в том, что вы печатаете $1и $2в блоке END{}. END{}запускается только один раз, после прочтения последней строки входного файла. Таким образом, $1и $2всегда будут 1-м и 2-м полем последней строки.

В любом случае, это невероятно неэффективный способ разбора текстового файла. Вы читаете все это для каждой итерации цикла. И циклы оболочки очень медленные. Итак, вы используете очень медленный цикл и , вы без необходимости читаете тысячи строк в своем awk снова и снова.

Вместо использования цикла оболочки просто делайте все в awk:

$ awk -F"\t" '/^[^#]/{var=0; for(i=10; i<=NF; i++) {if(substr($i,1,3)!="0|0") var++} print $1 ":" $2 "\t" var }' foo.vcf 
21:9411245  0
21:9411246  1

Или, чуть менее сжато:

awk -F"\t" '/^[^#]/{
        var=0; 
        for(i=10; i<=NF; i++) {
            if(substr($i,1,3)!="0|0"){
                var++
            } 
        }
        print $1 ":" $2 "\t" var 
    }' foo.vcf 

Пояснение

  • -F"\t":установить разделитель полей ввода на табуляцию.
  • /^[^#]/{... }:сделайте это только для строк, которые начинаются(/^a/будут соответствовать строкам, начинающимся сa)с символом, который не является#([^#]).
  • var=0;:установить varобратно на 0 для каждой входной строки.
  • for(i=10; i<=NF; i++) {if(substr($i,1,3)!="0|0") var++}:это ваш исходный код, он подсчитывает, сколько раз он находит генотип, который не является 0|0.
  • print $1 ":" $2 "\t" var:снова ваш код, но теперь за пределами блока END{}, поэтому он выполняется в каждой строке, а не только в конце.

Вот именно. Нет необходимости в цикле оболочки, и это займет всего несколько секунд.

1
27.01.2020, 23:40

Теги

Похожие вопросы