Находить и заменять символы перед ":"

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

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

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

Ответ 1

Вот два способа сделать это в 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))

Ответ 2

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

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

Подробнее см. ?regex или ?gsub.

Ответ 3

В R. Есть, конечно, более двух способов. Здесь другой.

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

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

Ответ 4

Использование sed:

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

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

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

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

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

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

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

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

Ответ 5

Вы можете использовать awk следующим образом:

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

Ответ 6

Если вы используете GNU coreutils, используйте cut:

cut -d: -f2 infile

Ответ 7

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

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

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

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

perl -pe 's/^.*://' file

Ответ 8

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

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))

Ответ 9

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

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)

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