Извлечь строки из большого файла, которые не заканчиваются на «H», в другой файл

Назначения временных переменных среды вступают в силу во время выполнения команды, а не раньше. В частности, они пока не действуют при разборе командной строки. Для иллюстрации рассмотрим две следующие команды:

$ A=1 sh -c "echo $A"

$ A=1 sh -c 'echo $A'
1

Разница между примерами команд состоит в том, что в первой команде подстановки переменных происходят перед sh -c , а во второй - во время выполнение sh -c .

Технически оболочка добавляет назначения временных переменных в среду дочернего процесса; они не добавляются в среду оболочки.

2
28.07.2016, 20:16
4 ответа

Основываясь на пояснении в комментариях,

sed -n '/^ATOM.*H$/!p' input > output

удалит (не печатает) строки, которые начинаются с «ATOM» и заканчиваются «H» из файла с именем input , и распечатывает остальную часть строк в файл с именем output . Синтаксис sed выглядит слева направо:

  • -n - не печатать строки по умолчанию
  • / ^ ATOM. * H $ / - искать строки, начинающиеся с ATOM , за которым следует любое количество символов, заканчивающееся ( $ ) на H
  • ! p - вывести строки, которые не соответствуют приведенному выше шаблону

A пример входного файла:

TITLE     Protein in water t=   0.00000
REMARK    THIS IS A SIMULATION BOX
ATOM      1  N   SER A 107      20.799  63.728  25.985  1.00  0.00           N
ATOM      2  H1  SER A 107      21.658  64.259  25.980  1.00  0.00           H
TITLE     Protein in water t=   0.00000H
REMARK    THIS IS A SIMULATION BOXH
ATOM      1  N   SER A 107      20.799  63.728  25.985  1.00  0.00           N
ATOM      2  H1  SER A 107      21.658  64.259  25.980  1.00  0.00           H

приводит к:

TITLE     Protein in water t=   0.00000
REMARK    THIS IS A SIMULATION BOX
ATOM      1  N   SER A 107      20.799  63.728  25.985  1.00  0.00           N
TITLE     Protein in water t=   0.00000H
REMARK    THIS IS A SIMULATION BOXH
ATOM      1  N   SER A 107      20.799  63.728  25.985  1.00  0.00           N

Более прямым синтаксисом sed будет:

sed '/^ATOM.*H$/d' input > output

, который говорит:

  • (по умолчанию вывести строки)
  • поиск строк, которые начинаются с ATOM и заканчиваются на H
  • удалить (не печатать) эти строки
3
27.01.2020, 22:11

С точки зрения длины командной строки, самое короткое, что я могу придумать, это:

grep -vx ATOM.\*H

С точки зрения скорости обработки, по крайней мере, в моей системе, самое быстрое из всех, что у меня есть найдено:

mawk '!/^ATOM.*H$/'
0
27.01.2020, 22:11

(НЕ ЛУЧШЕЕ РЕШЕНИЕ, согласно комментариям ниже)

Вы также можете сделать:

grep '[H $]' исходный файл> целевой-файл

Поместите «H $» (что означает « заканчивается на H ") в квадратных скобках отрицает это. Таким образом, grep будет отмечать записи, которые не соответствуют "H $"

-3
27.01.2020, 22:11

Инструмент для выбора строк на основе их содержимого - это grep , если правило выбора содержимого может быть выражено в виде регулярного выражения .

Регулярным выражением «начинается с ATOM » является ^ ATOM . Регулярное выражение «заканчивается на H » - H $ . Поскольку они не могут перекрываться, регулярное выражение для «начинается с ATOM , затем содержит что угодно и заканчивается на H » - это ^ ATOM. * H $ .

Чтобы выбрать строки, не соответствующие регулярному выражению, используйте параметр -v .

grep -v '^ATOM.*H$' large_file.txt >not_atom_h.txt

Для более общих условий, особенно для формата на основе столбцов, вы можете использовать awk . Вот программа awk, эквивалентная вашим образцам данных: она печатает строки, в которых первый столбец не является ATOM , или последний столбец не является H . В этом конкретном случае у awk нет преимущества, он будет медленнее, а не проще. Я упоминаю об этом, потому что небольшие вариации вашей проблемы, например, добавление столбца после столбца, который может быть или не быть H , значительно затруднят решение с помощью grep.

awk '$1 != "ATOM" || $NF != "H"' large_file.txt >not_atom_h.txt
2
27.01.2020, 22:11

Теги

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