Как выполнить многократный поиск строк для одной и той же команды? - PullRequest
0 голосов
/ 23 мая 2019

У меня есть разделенный пробелами файл, который выглядит следующим образом:

$ cat in_file
GCF_000046845.1_ASM4684v1_protein.faa WP_004920342.1 Chal_sti_synt_C
GCF_000046845.1_ASM4684v1_protein.faa WP_004927566.1 Chal_sti_synt_C
GCF_000046845.1_ASM4684v1_protein.faa WP_004919950.1 FAD_binding_3
GCF_000046845.1_ASM4684v1_protein.faa WP_004920342.1 FAD_binding_3

Я использую следующий скрипт оболочки, использующий grep для поиска строк:

$ cat search_script.sh
grep "GCF_000046845.1_ASM4684v1_protein.faa WP_004920342.1" Pfam_anntn_temp.txt
grep "GCF_000046845.1_ASM4684v1_protein.faa WP_004920342.1" Pfam_anntn_temp.txt

Проблема заключается вчто я хочу, чтобы каждая команда grep возвращала только первый экземпляр строки, которую она находит exclusive из результатов предыдущей идентичной команды grep.

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

$ cat out_file
GCF_000046845.1_ASM4684v1_protein.faa WP_004920342.1 Chal_sti_synt_C
GCF_000046845.1_ASM4684v1_protein.faa WP_004920342.1 FAD_binding_3

, в которой строка 1 является исключительно выводом первой команды grep, а строка 2 - исключительно выводом второй команды grep.Как мне это сделать?

PS Я запускаю это на большом файле (> 125 000 строк).Итак, search_script.sh в основном состоит из уникальных команд grep.Выполнение идентичных команд испортило мой последующий анализ.

Ответы [ 2 ]

1 голос
/ 23 мая 2019

Я предполагаю, что вы генерируете search_script.sh автоматически из содержимого in_file.Если вы можете посчитать, сколько раз вы будете повторять одну и ту же команду grep, вы можете просто использовать grep один раз и использовать head, например, если вы знаете, что будете использовать ее 2 раза:

grep "foo" bar.txt | head -2

Выведет первые 2 вхождения "foo" в bar.txt.

Если вам нужно выполнять команды grep отдельно, например, если между командами grep есть другой код, вы можете смешивать head и tail:

grep "foo" bar.txt | head -1 | tail -1

Some other commands...

grep "foo" bar.txt | head -2 | tail -1
  • head -n отображает первые n строки ввода
  • tail -n отображает последние n строки ввода

Если вы действительно ДОЛЖНЫ всегда использоватьта же команда, но убедитесь, что выходные данные всегда различаются. Единственный способ, которым я могу придумать, - это использовать временные файлы и сложную последовательность команд:

 cat foo.bar.txt.tmp 2>&1 | xargs -I xx echo "| grep -v \\'xx\\' " | tr '\n' ' '  | xargs -I xx sh -c "grep 'foo' bar.txt xx | head -1 | tee -a foo.bar.txt.tmp"

Итак, для объяснения этой команды, приведенной foo в качестве строки поиска и bar.txt в качестве имени файла, тогда foo.bar.txt.tmp - это уникальное имя для временного файла.Временный файл будет содержать строки, которые уже были выведены:

  • cat foo.bar.txt.tmp 2>&1: выводит содержимое временного файла.Если ничего не присутствует, выводит сообщение об ошибке в stdout (важно, потому что, если вывод был пустым, остальная часть команды не будет работать.)
  • xargs -I xx echo "| grep -v \\'xx\\' " добавляет | grep -v к началу каждогострока во временном файле grep -v something исключает строки, которые включают something.
  • tr '\n' ' ' заменяет символы новой строки пробелами, чтобы в одной строке была последовательность grep -v s.
  • xargs -I xx sh -c "grep 'foo' bar.txt xx | head -1 | tee -a foo.bar.txt.tmp" запускает новую команду, grep 'foo' bar.txt xx | head -1 | tee -a foo.bar.txt.tmp, заменяя xx предыдущим выводом.xx должна быть последовательностью grep -v с, исключающей предыдущие выходы.
  • head -1 обеспечивает вывод только одной строки за раз
  • tee -a foo.bar.txt.tmp добавляет новый вывод квременный файл.

Просто обязательно очистите временные файлы rm *.tmp в конце вашего скрипта.

0 голосов
/ 23 мая 2019

Если я правильно понял вопрос и вы хотите удалить дубликаты на основе последнего поля каждой строки, попробуйте выполнить следующее (это должно быть простой задачей для awk).

awk '!a[$NF]++'  Input_file
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...