С помощью GNU sed
вы можете:
sed -E 's/(\|[^ |]+) /\1| /
s/(([^|]* )?([^|]*))\|(([^ ]*)(.*))/\1\6\n\2\4/
/\n/P;D' <infile
... который печатает ...
TMPRSS2 AADAT Sample1
pp9284 AADAT Sample1
ERG TMPRSS2 Sample2
ERG pp9284 Sample2
TMPRSS2 ETV1 Sample3
pp9284 ETV1 Sample3
PDE4A MIA Sample4
PDE4A MIA-RAB4B Sample4
PDE4A RAB4B Sample4
PDE4A RAB4B-EGLN2 Sample4
PDE4A EGLN2 Sample4
Он работает путем разделения и печать с последующим частичным удалением содержимого строки на дополнительных \ n
символах ewline. Команда P
P
печатает только до первой появившейся \ n
строки в пространстве шаблонов, поэтому вы можете довольно легко распечатать только часть своего буфера редактирования как тебе нравится.
В этом случае для каждого разделенного на конвейер раздела, не содержащего пробелов, sed
помещает все биты на обоих концах буфера редактирования дважды. sed
вставляет крайний левый и крайний правый концы слева и справа от самой левой секции, разделенной на каналы, и следует этой последовательности с помощью \ n
ewline, затем он помещает те же выборки в любой конец всех разделенных трубопроводами секций, которые остаются с правой стороны его вставленной \ n
прямой линии. Итак, sed
может P
ринтировать только бит слева, если в пространстве шаблонов вообще есть \ n
ewline, тогда D
выберите только до первой встречающейся \ n
строки ewline в пространстве шаблонов и повторите попытку.
Самая первая подстановка происходит только один раз - она просто добавляет канал к концу секций, разделенных трубкой, так что всегда будет канал для разделения - даже для последнего случая.В остальное время sed
выполняет одно s ///
ubstitution, P
записывает первую строку в пространстве шаблонов, затем D
избирает то же самое. Когда он больше не может этого делать, он D
удаляет все пространства шаблонов и автоматически вставляет следующую строку ввода.
Чтобы сделать то же самое, можно написать POSIX BRE:
sed ' s/\(|[^ |]\{1,\}\) /\1| /
s/^\(\( *[^ |]* *\)*\([^ |]*\)\)|\(\([^ ]*\)\(.*\)\)/\1\6\
\2\4/; /\n/P;D' <infile
Вы не можете комбинировать обратное и прямое сопоставление в одном grep
вызове
Вы можете сделать это с помощьюsed
:
sed -e '/^www\./d' -e '/\//d' -e '/^[^.]*\.[^.]*$/!d'./*.txt
Или awk
(, который, в отличие от sed
, сможет напечатать имя соответствующего файла, напримерgrep
):
awk -F. 'NF == 2 && !/^www\./ && !/\// {print FILENAME": "$0}'./*.txt
Вы можете сделать это с помощью двух вызовов grep, если вы не хотите, чтобы имена файлов печатались:
cat./*.txt | grep '^[^.]*\.[^.]*$' | grep -v -e / -e '^www\.'
Здесь используется cat
для подачи содержимого всех файлов на стандартный ввод, поэтому первый grep
не печатает имена файлов. В некоторых grep
реализациях есть grep -h
пропуск вывода имен файлов, если файлов больше одного. В случае только одного имени файла grep
все равно не печатает имя файла, и вы можете передать его на стандартный ввод с перенаправлениями:
<onefile.txt grep '^[^.]*\.[^.]*$' | grep -v -e / -e '^www\.'
Вы можете реализовать отрицание с помощью (?!...)
негативного просмотра -опережающих операторов PCRE, если ваш grep
поддерживает-P
:
grep '^(?!www\.)(?!.*/)[^.]*\.[^.]*$'./*.txt
Но здесь вы могли бы сделать все это с -v
с:
grep -v -e / -e '^www\.' -e '^[^.]*$' -e '\..*\.'
Это также исключает строки, не содержащие точки, и строки, содержащие более одной точки.