Я хочу к grep данные после >
& |
. Я использовал эту команду:
grep -o ' |.*$'| cut -c5-
Но это просто дает данные после |
:
> Aminobenzoate
Asthma | Atrazine
Autoimmune thyroid disease | Bacterial
B cell receptor signaling pathway | Benzoate
Bile secretion | beta-Lactam
> Biosynthesis
Caffeine metabolism | Caprolactam
Calcium signaling pathway | Carbapenem
Aminobenzoate
Atrazine
Bacterial
Benzoate
beta-Lactam
Biosynthesis
Caprolactam
Carbapenem
Я предложил бы использовать sed
для этого:
sed 's/.*[|>] *//'
Это работает на Ваш пример, но Вы, возможно, должны адаптировать его, в зависимости от того, что сделать со строками без любого |
или >
. Если они должны быть удалены полностью, используйте
sed -n 's/.*[|>] *//p'
, Это означает, не производят по умолчанию (опция -n
), но печатают строку (p
), если эти s
команда могла бы выполнить замену.
awk
может использоваться также. Можно использовать несколько разделителей полей с помощью -F
с awk
для получения и >
и |
. Также может использовать sub
опция освободить сначала ведущее место, которые появляются перед текстом, когда это печатает столбцы соответствия:
awk -F'[>|]' '{sub(/^\ /, "",$2); print $2}' file.txt
Используя awk:
awk -F'[>|]' '{print$2}' input.txt | awk -F' ' '{print$1}'
ИЛИ
Предложенный Sergiy Kolodyazhnyy
awk -F'[>|]' '{print substr($2,2)}' input.txt
В первую очередь, я полагаю, что это diff -y
вывод, таким образом, можно также включать <
также.
Мы можем только использовать grep, чтобы сделать, это через оглядывается:
grep -Po "(?<=(\||<|>)\s).*" file.txt
.*
Ищут что-либо любые повторенные времена. (?<=(\||<|>)\s)
, который находится позади одного из них (|
или <
или >
) сопровождается пространством. более ясная версия:
grep -Po '(?<=[<|>]\s).*' file.txt
<час> Или использование grep
и cut
, поскольку Вы пробовали:
grep -Eo "(<|>|\|).*" file.txt | cut -f2 -d' '
-E
: расширенный grep
-o
Печать только подобранные средства части (<|>|\|)
<
или |
или >
. .*
каждая вещь & любые времена повторились Который бриги нас к этой точке:
enter code here
> Aminobenzoate
| Atrazine
| Bacterial
| Benzoate
| beta-Lactam
> Biosynthesis
| Caprolactam
| Carbapenem
затем использование cut
мы получаем второе поле, которое является нашими строками, который является:
Aminobenzoate
Atrazine
Bacterial
Benzoate
beta-Lactam
Biosynthesis
Caprolactam
Carbapenem
Наименьшее количество объема модификации от Вашей текущей команды состояло бы в том, чтобы заменить Ваше упоминание литералу |
символ в Вашем regex к ссылке на класс символов, содержащий и |
и >
, [|>]
, который будет соответствовать любому из них:
grep -o ' [|>].* Другие исследовали awk
, sed
и perl
реализации, но Ваш grep
реализация могла также быть улучшена далее.
, Например, Вы могли избавиться от эти cut
команда следующими способами:
- при помощи Perl
\K
флаг: grep -Po '[>|]\s*\K.*
- при помощи lookbehind PCRE:
grep -Po '(?<=[|>]\s).*'
примечание, что это будет только работать с установленной суммой пробелов между разделителем и выходным словом как механизмы PCRE, не требуется, чтобы реализовывать переменную ширину lookbehind и обычно делать нет.
| cut -c5-
Другие исследовали awk
, sed
и perl
реализации, но Ваш grep
реализация могла также быть улучшена далее.
, Например, Вы могли избавиться от эти cut
команда следующими способами:
\K
флаг: grep -Po '[>|]\s*\K.*
grep -Po '(?<=[|>]\s).*'
примечание, что это будет только работать с установленной суммой пробелов между разделителем и выходным словом как механизмы PCRE, не требуется, чтобы реализовывать переменную ширину lookbehind и обычно делать нет. Вот острота жемчуга, которая делает задание:
$ perl -ne 's/^.*[|>]\ //;print' inp.txt
Aminobenzoate
Atrazine
Bacterial
Benzoate
beta-Lactam
Biosynthesis
Caprolactam
Carbapenem
Или еще короче, как предложено Matija Nalis в комментариях
perl -pe 's/^.*[|>]\ //' inp.txt
Это в основном берет и удаляет все с начала строки до также |
или >
, и затем материал печати.
Если Вы еще не заметили, все ответы здесь воздействуют на идею удалить ведущую информацию. То, что мы также можем сделать, является группой, что мы хотим и заменяем целую строку этим. Фокус это не находится на ведущей информации, а на материале, который мы на самом деле хотим в выводе.
Возьмите, например, это sed
$ sed 's/^.*[>|] \(.*$\)/\1/' inp.txt
Aminobenzoate
Atrazine
Bacterial
Benzoate
beta-Lactam
Biosynthesis
Caprolactam
Carbapenem
То, что происходит, является этим независимо от того, что внутри \(
и \)
будет рассматриваться как целые вещи и сослался через \1
. Эта команда в основном говорит, "берут то, что прибывает после >
или |
плюс пространство и делают его как одну группу и замену, что целая строка с тем, что мы помещаем в это \1
группа.
В то время как сценарии Python могут быть немного более длинными, они являются обычно более читаемыми и явными. Вот то, что мы могли сделать со сценарием Python 3:
#!/usr/bin/env python3
import sys
import re
with open(sys.argv[1]) as fd:
for line in fd:
print(re.split("<|>|\|",line.strip())[1].strip())
Ключевые идеи здесь следующие:
re.split()
функция, мы разделяем каждую строку на использование списка >
или |
или >
как разделитель.[1]
в списке, потому что списки запускаются в индексе 0), объект в том списке и использование strip()
функция удаляет ведущий и запаздывающий пробел.re.split()
и извлечение списка происходит в print()
функция, поэтому после того как все те операции сделаны, мы заставляем желаемую выходную строку и движение обрабатывать следующую строкуЕсли бы мы хотели, то мы могли бы всегда пихать все в остроту как так:
$ python -c 'import re,sys;print("\n".join([ re.split("<|>|\|",l.strip())[1].strip() for l in sys.stdin]))' < inp.txt
Aminobenzoate
Atrazine
Bacterial
Benzoate
beta-Lactam
Biosynthesis
Caprolactam
Carbapenem
diff
вывод как ответ Ravexina предполагает, что мы можем всегда включать <
во все выражения, представленные здесь путем добавления <
в квадратные скобки. Таким образом мы будем иметь: perl -pe 's/^.*[|><]\ //;' inp.txt
sed 's/^.*[><|] \(.*$\)/\1/' inp.txt
<