Назначения временных переменных среды вступают в силу во время выполнения команды, а не раньше. В частности, они пока не действуют при разборе командной строки. Для иллюстрации рассмотрим две следующие команды:
$ A=1 sh -c "echo $A"
$ A=1 sh -c 'echo $A'
1
Разница между примерами команд состоит в том, что в первой команде подстановки переменных происходят перед sh -c
, а во второй - во время выполнение sh -c
.
Технически оболочка добавляет назначения временных переменных в среду дочернего процесса; они не добавляются в среду оболочки.
Основываясь на пояснении в комментариях,
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
, который говорит:
С точки зрения длины командной строки, самое короткое, что я могу придумать, это:
grep -vx ATOM.\*H
С точки зрения скорости обработки, по крайней мере, в моей системе, самое быстрое из всех, что у меня есть найдено:
mawk '!/^ATOM.*H$/'
(НЕ ЛУЧШЕЕ РЕШЕНИЕ, согласно комментариям ниже)
Вы также можете сделать:
grep '[H $]' исходный файл> целевой-файл
Поместите «H $» (что означает « заканчивается на H ") в квадратных скобках отрицает это. Таким образом, grep будет отмечать записи, которые не соответствуют "H $"
Инструмент для выбора строк на основе их содержимого - это 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