Удалить весь текст перед двоеточием

У меня есть файл, содержащий определенное количество строк. Каждая строка выглядит так:

TF_list_to_test10004/Nus_k0.345_t0.1_e0.1.adj:PKMYT1

Я хотел бы удалить все символы перед ":", чтобы сохранить только PKMYT1, который является именем гена. Поскольку я не являюсь экспертом в области сценариев регулярных выражений, может ли кто-нибудь помочь мне сделать это с помощью Unix (sed или awk) или в R?

10 ответов

Решение

Вот два способа сделать это в R:

foo <- "TF_list_to_test10004/Nus_k0.345_t0.1_e0.1.adj:PKMYT1"

# Remove all before and up to ":":
gsub(".*:","",foo)

# Extract everything behind ":":
regmatches(foo,gregexpr("(?<=:).*",foo,perl=TRUE))

Простое регулярное выражение, используемое с gsub():

x <- "TF_list_to_test10004/Nus_k0.345_t0.1_e0.1.adj:PKMYT1"
gsub(".*:", "", x)
"PKMYT1"

Увидеть ?regex или же ?gsub для получения дополнительной помощи.

Есть, конечно, более двух способов в R. Вот еще один.

unlist(lapply(strsplit(foo, ':', fixed = TRUE), '[', 2))

Если строка имеет постоянную длину, я представляю substr будет быстрее, чем это или методы регулярных выражений.

Используя sed:

sed 's/.*://' < your_input_file > output_file

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

Согласно комментарию Джоша О'Брайена, если вы хотите заменить только до первой колонки включительно, сделайте следующее:

sed "s/[^:]*://"

Это будет соответствовать всему, что не является двоеточием, затем следует двоеточие, и заменяется ничем.

Обратите внимание, что для обоих этих шаблонов они будут останавливаться на первом совпадении в каждой строке. Если вы хотите сделать замену для каждого совпадения в строке, добавьте ' g '(глобальная) опция до конца команды.

Также обратите внимание, что в Linux (но не в OSX) вы можете редактировать файл на месте с помощью -i например:

sed -i 's/.*://' your_file

Решение с использованием str_remove из stringr упаковка:

      str_remove("TF_list_to_test10004/Nus_k0.345_t0.1_e0.1.adj:PKMYT1", ".*:")
[1] "PKMYT1"

Ты можешь использовать awk как это:

awk -F: '{print $2}' /your/file

Некоторым очень простым шагом, который я пропустил из лучшего ответа @Sacha Epskamp, ​​было использование функции sub, в данном случае, чтобы взять все до ":"(вместо удаления), так что это было очень просто:

foo <- "TF_list_to_test10004/Nus_k0.345_t0.1_e0.1.adj:PKMYT1"

# 1st, as she did to remove all before and up to ":":
gsub(".*:","",foo)

# 2nd, to keep everything before and up to ":": 
gsub(":.*","",foo)

По сути, то же самое, просто измените позицию ":" внутри под-аргумента. Надеюсь, это поможет.

Я работал над аналогичной проблемой. Советы Джона и Джоша О'Брайена сделали свое дело. Я начал с этого тибля:

library(dplyr)
my_tibble <- tibble(Col1=c("ABC:Content","BCDE:MoreContent","FG:Conent:with:colons"))

Это выглядит как:

  | Col1 
1 | ABC:Content 
2 | BCDE:MoreContent 
3 | FG:Content:with:colons

Мне нужно было создать этот кусок:

  | Col1                  | Col2 | Col3 
1 | ABC:Content           | ABC  | Content 
2 | BCDE:MoreContent      | BCDE | MoreContent 
3 | FG:Content:with:colons| FG   | Content:with:colons

И сделал это с этим кодом (версия R 3.4.2).

my_tibble2 <- mutate(my_tibble
        ,Col2 = unlist(lapply(strsplit(Col1, ':',fixed = TRUE), '[', 1))
        ,Col3 = gsub("^[^:]*:", "", Col1))

Если у вас есть GNU coreutils доступное использование cut:

cut -d: -f2 infile

Ниже приведены 2 эквивалентных решения:

Первый использует Perl -a функция автоматического разделения для разделения каждой строки на поля с помощью :заселить F массив полей и выведите 2-е поле $F[1] (считается начиная с поля 0)

perl -F: -lane 'print $F[1]' file

Вторая использует регулярное выражение для замены s/// от ^ начало строки, .*: любые символы, заканчивающиеся двоеточием, ни с чем

perl -pe 's/^.*://' file
Другие вопросы по тегам