фильтрация файла по двум условиям

Каждый процесс оболочки имеет собственное представление о том, что такое история строки команды -. Когда интерактивная оболочка завершает работу, она записывает свою запомненную историю в ~/.bash_historyдля следующей оболочки, но это степень взаимодействия между процессами оболочки.

В вашей команде ()делает вилку оболочки копией самой себя для запуска команды history -d.Дочерний процесс начинается с копии внутреннего состояния родителя, поэтому он знает историю и может вносить изменения в свою копию.

Однако, когда подоболочка завершает работу, ее копия истории (, которая была только что перезаписана ), отбрасывается вместе с остальной частью ее внутреннего состояния ). Подоболочка знает, что это подоболочка, поэтому она даже не удосуживается написать ~/.bash_history.


Сценарий без источника обычно вообще не может манипулировать историей, потому что он интерпретируется свежей не-интерактивной оболочкой, которая даже не читает ~/.bash_historyпри запуске.

Вы можете заставить оболочку вести себя как интерактивную, указав ее в командной строке:

#!/bin/bash -i
echo something

Оболочка, которая запускает этот скрипт, добавит свои команды (, которые включают в себя как строку shebang, так и echo something), к ~/.bash_history, которую она находит на диске. Но, конечно, это не влияет на -копию истории памяти процесса оболочки, вызывающего сценарий, и когда он выходит, изменения, внесенные сценарием в ~/.bash_history, в любом случае будут потеряны.

1
03.10.2020, 16:28
2 ответа

Вот еще один способ:

$ awk -F'[;=]' '$10>=95 && $8 == 100' file
ID=NbD053289.1.mrna1;Name=NbD053289.1;Parent=NbD053289.1.path1;coverage=100.0;identity=100.0;matches=702;mismatches=0;indels=0;unknowns=0
ID=NbD053288.1.mrna1;Name=NbD053288.1;Parent=NbD053288.1.path1;coverage=100.0;identity=99.8;matches=482;mismatches=1;indels=0;unknowns=0

Хитрость заключается в том, чтобы установить разделитель полей на ;или=(это то, что делает -F'[;=]'). Тогда значение для identityбудет 10-м полем, а значение для coverageбудет 8-м. Поскольку действие awkпо умолчанию, когда выражение оценивается как истинное, заключается в печати текущей строки, это означает, что $10>=95 && $8 == 100будет печатать любые строки, соответствующие обоим этим условиям.


На самом деле вы могли бы сделать это и с GNU grep, но вам не нужна опция -o, так как вам нужна вся строка, и нет причин использовать просмотр назад. Все, что вам нужно, это определить диапазон. Поскольку вам нужны значения от 95до 100(>=95), это означает, что вы хотите либо 9, за которым следует любое число от 5до 9, либо100:

$ grep  -P 'coverage=100.0.*identity=(9[5..9]|100)' file 
ID=NbD053289.1.mrna1;Name=NbD053289.1;Parent=NbD053289.1.path1;coverage=100.0;identity=100.0;matches=702;mismatches=0;indels=0;unknowns=0
ID=NbD053288.1.mrna1;Name=NbD053288.1;Parent=NbD053288.1.path1;coverage=100.0;identity=99.8;matches=482;mismatches=1;indels=0;unknowns=0

Обратите внимание, что я предполагаю, что идентичность не может принимать значения больше 100, что кажется безопасным предположением, поскольку вы, вероятно, смотрите на сохранение последовательности, и вы не можете получить больше сходства, чем 100% идентичности.

4
18.03.2021, 23:00

сначала преобразуем поле в число, используя

awk -F= 'NR==1 { for(i=1;i<=NF;i++) printf "%2d %s\n",i,$i ;}' file
 1 ID
 2 NbD053289.1.mrna1;Name
 3 NbD053289.1;Parent
 4 NbD053289.1.path1;coverage
 5 100.0;identity
 6 100.0;matches
 7 702;mismatches
 8 0;indels
 9 0;unknowns
10 0

поэтому покрытие равно 5, а идентичность равна 6

Затем мы не можем напрямую использовать awk ==, так как он будет соответствовать строке, поэтому мы конвертируем в число, используя +1.

этот доход

awk -F= '$6+1>96 && ($5+1) == 101' file
ID=NbD053289.1.mrna1;Name=NbD053289.1;Parent=NbD053289.1.path1;coverage=100.0;identity=100.0;matches=702;mismatches=0;indels=0;unknowns=0
ID=NbD053288.1.mrna1;Name=NbD053288.1;Parent=NbD053288.1.path1;coverage=100.0;identity=99.8;matches=482;mismatches=1;indels=0;unknowns=0

где

  • -F=указать awk использовать =в качестве разделителя
  • $6+1>96преобразовать в число, как описано выше, и отфильтровать
2
18.03.2021, 23:00

Теги

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