Как заменить все, кроме определенного шаблона, на sed?

Вам действительно нужно использовать кошку?

cat -n  thefile | tail -n1 

Что вы имеете в виду, говоря «Выделите ключевые слова, показывая при этом полное содержимое файла»?

Какие ключевые слова вы хотите выделить?

С какой целью пронумеровать все абзацы, но показать только последний? (ПРИМЕЧАНИЕ: команда, которую я напишу, сделает именно это: cat -n для нумерации абзацев и tail -n1 для отображения только последнего абзаца.)

2
01.07.2017, 03:21
4 ответа

Для данного ввода, как указано, это sedвыражение, кажется, делает то, что вы просите:

$ cat input
`>TRINITY_DN75270_c3_g2::TRINITY_DN75270_c3_g2_i4::g.22702::m.22702 [sample]`
$ sed 's/^.*::\([A-Z_0-9a-z]*\)::.*\[\(.*\)\].*/\1[\2]/' input
TRINITY_DN75270_c3_g2_i4[sample]

Магия заключается в использовании групп регулярных выражений и двух обратных ссылок для восстановления желаемого результата. разъяснить:

NODE                     EXPLANATION
--------------------------------------------------------------------------------
  ^                        the beginning of the string
 .*                       any character except \n (0 or more times
                           (matching the most amount possible))
  ::                       '::'
  \(                       group and capture to \1:
    [A-Z_0-9a-z]*            any character of: 'A' to 'Z', '_', '0'
                             to '9', 'a' to 'z' (0 or more times
                             (matching the most amount possible))
  \)                       end of \1
  ::                       '::'
 .*                       any character except \n (0 or more times
                           (matching the most amount possible))
  \[                       '['
  (                        group and capture to \2:
   .*                       any character except \n (0 or more times
                             (matching the most amount possible))
  )                        end of \2
  \]                       ']'
 .*                       any character except \n (0 or more times
                           (matching the most amount possible))

Итак, \1— это первый ключ, который вы хотели извлечь, а \2— это то, что будет в квадратных скобках после него. Затем Is реконструируется с помощью \1[\2]/, создавая желаемый результат.

5
27.01.2020, 21:52

Предполагая, что вы хотите сохранить второе поле между разделителями ::+ [sample], поэтому, удалив все до и после поля до последнего пробела , вы можете:

sed 's/^[^:]*::\([^:]*\)::.* /\1/'  

Это будет соответствовать от начала строки до последнего последующего пробела(.*"жадного" )и заменить его просто первым выражением "sub -" (помечено экранированными скобками ).

Подробнее о обратных ссылках и подвыражениях -см. это описание на gnu.org .

1
27.01.2020, 21:52
sed -e '
   s/::/\n/; s//\n/
   s/.*\n\(.*\)\n.*\(\[[^]]*]\).*/\1\2/
' data

Мы выделяем идентификатор, заменяя ::, встречающиеся 1-й и 2-й раз. Затем убираем все, кроме отмеченного региона + [...] региона

Результаты:

TRINITY_DN75270_c3_g2_i4[sample]
2
27.01.2020, 21:52

awkальтернатива:

awk -F'::' '{ match($NF,/\[.+\]/); print $2 substr($NF,RSTART,RLENGTH) }' file

Выход:

TRINITY_DN75270_c3_g2_i4[sample]

  • -F'::'-рассматривая ::как разделитель полей
2
27.01.2020, 21:52

Теги

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