Как удалить строки с числом меньше чем 60 в столбце 3?

У меня есть большой файл. Я должен удалить все строки в файле, которые имеют число меньше чем 60 в столбце 3.

Файл в качестве примера:

35110   Bacteria(100)   Proteobacteria(59)  Alphaproteobacteria(59)
12713   Bacteria(100)   Bacteroidetes(100)  Bacteroidia(100)

Желаемый вывод:

12713   Bacteria(100)   Bacteroidetes(100)  Bacteroidia(100)
6
задан 13 February 2018 в 04:26

4 ответа

Никакая потребность в расширениях Простофили:

awk -F '[()]' '$4 >= 60'

Здесь awk полевой токенизатор, указанный через -F набор regex []: поля разделяются или открытием или закрывающей скобкой, следовательно Вы видите, что число Вашего 3-го столбца является 4-м awk полем.

8
ответ дан 23 November 2019 в 07:20

Можно использовать awk (на самом деле это должна быть реализация AWK GNU gawk, нет mawk который содержит меньше функций - Вам, возможно, придется установить его sudo apt install gawk) для этого задания:

gawk '{match($3,/\((.+)\)/,m);if(m[1]>=60){print $0}}' MY_FILE

Теперь, хотя по общему признанию это похоже на черную магию к нетренированному глазу, логика проста:

  • Для каждой строки, выполненной материал в наиболее удаленных фигурных скобках:
  • Во-первых, match($3, /\((.+)\)/, m) соответствует регулярному выражению \((.+)\) (который соответствует открытию и закрытию круглой скобки, храня содержание между скобками как первая группа получения) против третьего столбца $3 из обработанной строки входа и хранилищ получающийся массив соответствия в переменной m.
  • Затем проверьте условие if (m[1] >= 60) т.е. если значение первой группы получения соответствия (независимо от того, что между скобками во входе) больше или равно 60. Если это верно, сделать {print $0}, который просто печатает целую в настоящее время обрабатываемую строку.
4
ответ дан 23 November 2019 в 07:20

Вот альтернатива жемчуга

perl -alne 'print unless $F[2] =~ /\((\d+)\)$/ && $1 < 60'
  • соответствуйте и получите заключенную в скобки последовательность десятичных цифр в конце 3-го (индексированного нулем) поля
  • если соответствие найдено, протестируйте численное значение и печать полученной группы соответственно

Напр.

$ perl -alne 'print unless $F[2] =~ /\((\d+)\)$/ && $1 < 60' file
12713   Bacteria(100)   Bacteroidetes(100)  Bacteroidia(100)

Обратите внимание, что это реализует логику, "удаляют все строки в файле, которые имеют число меньше чем 60 в столбце 3", как указано в Вашем вопросе - который немного отличается от печати строк, которые имеют число, больше, чем или равный 60.


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

perl -F, -lne 'print unless $F[2] =~ /\((\d+)\)$/ && $1 < 60'
3
ответ дан 23 November 2019 в 07:20

Если Вы не хотите изучать/использовать инструменты командной строки, Вы могли бы также открыть файл в LibreOffice Calc и просто отфильтровать данные (Calc поддерживает разделенные от вкладки файлы).

Если Вы знаете какой-либо язык программирования, то это тривиально для записи небольшой программы для фильтрации данных.

Но если бы у Вас есть большой набор данных для обработки, использование DBMS как MySQL было бы легче, быстрее и интуитивным.

0
ответ дан 23 November 2019 в 07:20

Другие вопросы по тегам:

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