Обработка индексных строк

Мой входной файл выглядит так:

#key string pos(string) key1 AA000AA000000AAA0A 2, 3, 18, 12 key2 00A00AAA000AAAA00A 3, 18 

И я бы хотел добавить новый столбец в конце каждой ключевой строки (разделенный вкладкой). Если A находится в столбце 2 входного файла, новый столбец будет содержать позиции, указанные в столбце 3 входного файла. Если в столбце 2 входного файла найдено 0 , позиция не должна печататься в новом столбце.

В принципе, это желаемый результат:

 #key string pos(string) Apos(string) key1 AA000AA000000AAA0A 2, 3, 18, 12 2, 18 key2 00A00AAA000AAAA00A 3, 18 3, 18 

Краткое объяснение:
(Ключ1)

  • строка с индексом 2 содержит A -> элемент 2 добавленный в новый столбец
  • строка в индексе 3 имеет 0 -> элемент 3 не добавленный в новый столбец
  • строка в индексе 12 имеет 0 -> элемент 12 не добавленный в новый столбец
  • строка в индексе 18 имеет элемент A -> 18 добавленный в новый столбец

Я делаю это на python, но я застрял в несколько раз для более ключей и элементов (строки довольно длинные для обработки), поэтому я подумал, что могу попросить ваши советы для решения командной строки (более легкое).

То, о чем я думал, это:

  • разделите поле pos (string), получите индекс, который я ищу в поле строки
  • получить символ в заданном индексе в строке
  • для утверждения (?)

Как насчет следующего скрипта awk :

 #!/usr/bin/awk -f BEGIN { FS="\t" print "#key\tstring\tpos(string)\tApos(string)" } { out="" printf "%s\t",$0 split($2,str,"") gsub(/ /,"",$3) split($3,pos,",") for (i in pos){ if (str[pos[i]]=="A"){ out = out pos[i] ", " } } gsub(/, $/,"",out) print out } 

Сохраните его как (например) findA.awk и сделайте его исполняемым с помощью chmod +x findA.awk .

Затем запустите его против ваших входных данных и перенаправьте вывод в новый файл:

 ./findA.awk input.txt > output.txt cat output.txt #key string pos(string) Apos(string) key1 AA000AA000000AAA0A 2, 3, 18, 12 2, 18 key2 00A00AAA000AAAA00A 3, 18 3, 18 

Результат не такой аккуратный, как ваш пример, поскольку он разделен на вкладку (согласно вашему запросу), а ширина табуляции не совпадает с шириной различных строк.

Я не уверен, как вы это делаете сейчас (было бы полезно увидеть ваш код Python), но вы можете создать список элементов столбца 3, который указывает на «A» в столбце 2, например:

[i for i in COLUMN3 if COLUMN2[i]=='A']

Это кажется простой проблемой, но, возможно, я не совсем понимаю ее. Возможно, вы забываете, что строки являются итерабельными?

Ужасный perl :

 $ perl -anle ' printf "%s Apos(string)\n",$_ and next if /^#/; printf "%s",$_; $len = 12 - length((split(/\s+/,$_,3))[-1]); for $pos_ss (@F[2..$#F]) { $char = substr($F[1],int($pos_ss)-1,1); push @res, int($pos_ss) if $char eq 'A'; } printf "%@{[12-4+$len]}s\n", join ", ",@res; @res=(); ' file #key string pos(string) Apos(string) key1 AA000AA000000AAA0A 2, 3, 18, 12 2, 18 key2 00A00AAA000AAAA00A 3, 18 3, 18 

Он работает аналогично моему решению для этого ответа , плюс добавляет переменную $len для вычисления формата, необходимого для печати последнего выравниваемого столбца.