Подсчет значений во втором и третьем столбцах, где значение первого столбца является постоянным/одинаковым

Ansible может перезагрузить сервер без использования spacecmd, используя команду reboot.

- name: Upgrading via spacewalk
  shell: spacecmd  system_upgradepackage   '*' -y
- name: Reboot after upgrades
  shell: reboot
  async: 0
  poll: 0
- name: Waiting for host to come up
  local_action: wait_for host={{ ansible_ssh_host }} state=started

Адаптировано из:https://www.linux.com/tutorials/ansible-reboot-server-play-book-and-wait-it-come-back

0
01.10.2021, 07:05
2 ответа

Сценарий awk, подобный тому, что показан ниже, будет собирать данные из данного файла и подсчитывать, сколько раз каждый столбец «тип» (встречается два и )для каждого «имени» (первый столбец ). Он выводит простой формат, подобный CSV -, который можно импортировать в другие программы, предполагая, что ни один из входных данных не содержит встроенных запятых.

{
        genes[$1] = 1
        for (i = 2; i <= NF; ++i) {
                types[$i] = 1
                counts[$1,$i]++
        }
}

END {
        OFS = ","

        $0 = "name"
        for (t in types)
                $(NF+1) = header[++n] = t
        print

        for (g in genes) {
                $0 = g
                for (i = 1; i <= n; ++i)
                        $(NF+1) = counts[g,header[i]]+0
                print
        }
}

Массивы genesи typesявляются ассоциативными массивами, которые содержат имена и типы в качестве ключей. Массив countsподсчитывает, сколько раз конкретное имя и тип встречаются как пара во входных данных.

Блок ENDсоздает и выводит заголовок, а затем перебирает все имена генов и выводит собранные значения для каждого типа.

Проверка:

$ awk -f script file
name,indel,Benign,Likely_pathogenic,snp,Pathogenic
GeneA,2,1,1,3,3
GeneB,1,2,0,2,1
GeneC,0,1,1,2,0
$ awk -f script file | column -t -s,
name   indel  Benign  Likely_pathogenic  snp  Pathogenic
GeneA  2      1       1                  3    3
GeneB  1      2       0                  2    1
GeneC  0      1       1                  2    0
$ awk -f script file | csvlook
| name  | indel | Benign | Likely_pathogenic | snp | Pathogenic |
| ----- | ----- | ------ | ----------------- | --- | ---------- |
| GeneA |     2 |      1 |              True |   3 |          3 |
| GeneB |     1 |      2 |             False |   2 |          1 |
| GeneC |     0 |      1 |              True |   2 |          0 |

(Если вы не хотите, чтобыcsvlookвыводил тип из данных, используйте его с опцией -I.)

1
01.10.2021, 09:32

Как сказано в поле «Комментарий», Ruby разрешен, у меня есть автономное решение, оно не требует конвейерной обработки разных программ:

Программа

data = <<~'EOF'
    GeneA Pathogenic snp
    GeneA Pathogenic snp
    GeneA Benign indel
    GeneA Likely_pathogenic snp
    GeneA Pathogenic    indel
    GeneB Benign    snp
    GeneB Pathogenic    snp
    GeneB Benign    indel
    GeneC  Benign   snp
    GeneC  Likely_pathogenic    snp
EOF

hash, header1, header2 = {}, [], []

data.each_line { |x|
    fields = x.split("\s")
    field = hash[fields[0].to_sym] ||= [{}, {}]

    field[0].merge!(fields[1] => 1) { |key, val1, val2| val1 + val2 }
    field[1].merge!(fields[2] => 1) { |key, val1, val2| val1 + val2 }
    header1 << fields[1]
    header2 << fields[2]
}

headers = header1.tap(&:uniq!).concat(header2.tap(&:uniq!))
header = '| ' + headers.join(' | ') + ' | '

puts header, ?- * header.length

hash.each { |k, v|
    v0, v1 = v[0], v[1]

    print "| #{k} |"
    headers.each_with_index { |x, i|
        out = "#{(v0[x] || v1[x]).to_i} |"
        print i == 0 ? out.rjust(5) : out.rjust(x.length + 3)
    }
    puts
}

Выполнить:

$ ruby thisFile.rb

Выход:

| Pathogenic | Benign | Likely_pathogenic | snp | indel | 
----------------------------------------------------------
| GeneA |  3 |      1 |                 1 |   3 |     2 |
| GeneB |  1 |      2 |                 0 |   2 |     1 |
| GeneC |  0 |      1 |                 1 |   2 |     0 |

Вы можете кричать на эти rjust(5), rjust(x.length + 3), потому что они жестко запрограммированы. На самом деле это для ' | ', которые также жестко запрограммированы. Если вы добавите еще один пробел, вы добавите единицу к числам. Он не сломается, если данные изменятся.

Вместо data <<~EOF...вы можете прочитать файл, содержащий данные, с помощью data = (ARGV[0] && File.readable?(ARGV[0])) ? IO.read(ARGV[0]) : ''-, здесь данные считываются из имени файла, переданного в качестве аргумента. Должен работать со всеми данными, но выравнивание делается на основе заголовка. Небольшая модификация этого кода может выравнивать данные на основе самого большого поля. Но пока я думаю, что это сделает вашу работу.

0
01.10.2021, 12:03

Теги

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