удаление расширений в столбце

удаление расширений в столбце

У меня есть такой файл

ILMN_1343291    TGTGTTGAGAGCTTCTCAGACTATCCACCTTTGGGTCGCTTTGCTGTTCG  NM_001402.5
ILMN_1343295    CTTCAACAGCGACACCCACTCCTCCACCTTTGACGCTGGGGCTGGCATTG  NM_002046.3
ILMN_1651209    TCACGGCGTACGCCCTCATGGGGAAAATCTCCCCGGTGACTTTCAGGTCC  NM_182838.1

Я хочу удалить числовые расширения из конца третьего столбца, чтобы мой выходной файл выглядел следующим образом:

ILMN_1343291    TGTGTTGAGAGCTTCTCAGACTATCCACCTTTGGGTCGCTTTGCTGTTCG  NM_001402
ILMN_1343295    CTTCAACAGCGACACCCACTCCTCCACCTTTGACGCTGGGGCTGGCATTG  NM_002046
ILMN_1651209    TCACGGCGTACGCCCTCATGGGGAAAATCTCCCCGGTGACTTTCAGGTCC  NM_182838

Как я могу сделать это в командной строке, желательно с помощью awk? Я могу сделать это в , perlно я почти уверен, что есть одна командная строка, чтобы сделать это.

решение1

С awk:

awk -F'.' '{print $1}' file

-Fопция изменения разделителя полей по умолчанию (пробел) на точку (.).
$1- это индекс позиции поля (с разделителем полей .).

{ILMN_1343291    TGTGTTGAGAGCTTCTCAGACTATCCACCTTTGGGTCGCTTTGCTGTTCG  NM_001402}.{5}
                  ^^ field index is $1                                          ^^$2

С rev и awk:

rev file | awk -F'.' '{print $2}'|rev # reverse characters of each lines,\
                                        print field number 2 with (.) separator \
                                        and reverse the result again

Утилита revкопирует указанные файлы в стандартный вывод, меняя порядок символов в каждой строке на обратный. Если файлы не указаны, считывается стандартный ввод.

С sed:

sed 's/.[0-9]*$//' file

sed 's/.[^.]*$//' file

$указать на конец строки. В первой команде sed найдите символ (.), за которым следует ноль или более вхождений цифр, и замените их пробелами.

Во второй команде sed удалите все, что следует за (.), а также удалите саму точку (.).

С rev и sed:

rev file| sed 's/.*[.]//' |rev

Удалите все перед точкой (.). Также включите и удалите саму точку .

С помощью grep:

grep -oP '.*(?=\.[0-9])' file
    -o, --only-matching
          Вывести только совпадающие (непустые) части совпадающей строки,
          с каждой такой частью на отдельной выходной линии.
    -P, --perl-regexp
          Интерпретировать PATTERN как регулярное выражение, совместимое с Perl (PCRE)

(?=pattern): Положительный просмотр вперед: конструкция положительного просмотра вперед представляет собой пару скобок, где за открывающейся скобкой следует вопросительный знак и знак равенства.

.*(?=\.[0-9]): (положительный просмотр вперед) соответствует всему( .*), за которым следует одна точка(.), и любым вхождениям цифр, не делая шаблон( \.[0-9]) частью совпадения.

С rev и grep:

rev file |grep -oP '(?<=[0-9]\.).*' |rev

rev file |grep -oP '[0-9]\.\K.*' |rev

(?<=pattern): Положительный ретроспективный анализ. Пара скобок, за открывающей скобкой следует вопросительный знак, символ «меньше» и знак равенства.

(?<=[0-9]\.).*(положительный просмотр назад) соответствует всему, за чем следуют любые вхождения цифр и которое заканчивается точкой (.).

Во второй команде grep вы можете использовать nifty \Kвместо утверждения lookbehind.

С разрезом:

cut -f1 -d. file

cut -c 1-77 file # Print first 77 characters of each line.
вырезать - удалить разделы из каждой строки файлов

-d, --delimiter=РАЗДЕЛИТЕЛЬ
      используйте DELIM вместо TAB для разделителя полей

-f, --fields=СПИСОК
      выберите только эти поля;

-c, --characters=СПИСОК
      выберите только эти символы

С циклом while:

while read line; do echo "${line::-2}";done <file

Это сработает, если в конце каждой строки есть только числа с длиной = 1, и они имеют фиксированную длину. Приведенная выше команда удаляет последние два символа в конце каждой строки во входном файле. Альтернативные команды: ${line%??}.

решение2

Предположим, что все расширения состоят из цифр:

perl -pi -e 's/\.\d+$//' /path/to/file

-iвыполняет редактирование на месте (как в sed). \dозначает цифры и $обозначает конец строки.

С awk:

awk 'gsub(/\.[0-9]+$/,"")' /path/to/file

gawkв новых версиях есть возможность редактирования на месте, но я не уверен, насколько она переносима. gsubподдерживает необязательный параметр, указывающий целевой столбец:

awk 'gsub(/\.[0-9]+$/,"",$3)' /path/to/file

Последняя форма имеет нежелательный побочный эффект, заключающийся в разделении каждого столбца одним пробелом в выводе, как если бы вы сделали print $1,..,$NF. Я не знаю, почему.

решение3

Использовать awkего просто, просто установите разделитель полей следующим образом .:

awk -F. '{print $1}' file

Другой подход с использованием оболочки (в данном случае bash):

while IFS=.; read -r lines _; do  line+=("$lines"); done <file                                                                           
printf "%s\n" "${line[@]}"
ILMN_1343291    TGTGTTGAGAGCTTCTCAGACTATCCACCTTTGGGTCGCTTTGCTGTTCG  NM_001402
ILMN_1343295    CTTCAACAGCGACACCCACTCCTCCACCTTTGACGCTGGGGCTGGCATTG  NM_002046
ILMN_1651209    TCACGGCGTACGCCCTCATGGGGAAAATCTCCCCGGTGACTTTCAGGTCC  NM_182838

решение4

Это удалит все, что начинается с точки:

sed 's/\..*//'

Связанный контент