Создайте новый файл в домашнем каталоге пользователя под названием .vimrc, если его там еще нет. Здесь мы будем одновременно создавать и редактировать с помощью vi
sudo vi ~/.vimrc
Добавьте следующие команды, которые включают отключение режима совместимости и функцию стирания клавиши backspace:
set nocp
set backspace=indent,eol,start
Сохраните и выйдите из файла с помощью
:wq
Отключение режима совместимости позволяет использовать клавиши со стрелками, к которым мы привыкли в старых vi.
Поскольку при создании файла мы использовали sudo'd, право собственности на файл, вероятно, будет принадлежать root. Вы можете передать права на файл пользователю chown.
В моем случае это было для raspberry pi, поэтому пользователь и группа - pi:
chown pi:pi ~/.vimrc
Теперь снова запустите vi и наслаждайтесь!
Вы просто хотите добавить столбец с количеством столбцов в нем. Это можно сделать с помощью awk
:
$ awk -F ',' '{ printf("%d,%s\n", NF, $0) }' data.in
3,Rv0729,Rv0993,Rv1408
4,Rv0162c,Rv0761c,Rv1862,Rv3086
1,Rv2790c
NF
- это переменная awk
, содержащая количество полей (столбцов) в текущей записи (строке). Мы печатаем это число, за которым следует запятая и оставшаяся часть строки для каждой строки.
Альтернатива (тот же результат, но может выглядеть немного чище):
$ awk -F ',' 'BEGIN { OFS=FS } { print NF, $0 }' data.in
FS
- это разделитель полей, который awk
использует для разделения каждой записи на поля, и мы установили для него значение запятая с -F ','
в командной строке (как в первом решении). OFS
- это разделитель полей вывода , и мы устанавливаем его таким же, как FS
перед чтением первой строки ввода.
Если вы хотите подсчитать количество вхождений шаблона Rv [0-9] {4} c?
, а не количество полей с разделителями-запятыми, как предполагает тема вашего вопроса, вы можете сделать:
awk '{print gsub(/Rv[0-9]{4}c?/, "&"), $0}'
Подход Perl:
$ perl -F, -pae 's/^/$#F+1 . ","/e' file
3,Rv0729,Rv0993,Rv1408
4,Rv0162c,Rv0761c,Rv1862,Rv3086
1,Rv2790c
Команда -a
заставляет perl
вести себя как awk
и разбивать каждую входную строку на строки, заданные -F
и сохранять результирующие поля в массив @F
. Поэтому $#F
будет наибольшим индексом массива @F
и, поскольку массивы начинают считаться с 0
, $#F+1
будет общим количеством элементов в массиве. -p
означает "вывести каждую строку ввода после аппликации скрипта, заданного -e
". s///
- это оператор подстановки, и здесь мы заменяем начало строки (^
) на количество полей + 1 и запятую ($#F+1 . ","
).
В вашем вопросе говорится, что столбец 3 содержит имена генов. Я предполагаю, что на самом деле вы ввели следующие данные:
column1 column2 Rv0729,Rv0993,Rv1408
column1 column2 Rv0162c,Rv0761c,Rv1862,Rv3086
column1 column2 Rv2790c
Каждое имя гена в столбце 3 содержит ведущую подстроку Rv
. Таким образом, мы можем посчитать их в python следующим образом:
$ python -c "import sys;print map(lambda x: x.split()[2].count('Rv'),sys.stdin.readlines())" < input.txt
[3, 4, 1]
Полученный список показывает количество генов в каждой строке, в соответствующем порядке. Если мы хотим сделать список более подробным и учесть возможность того, что гены могут не содержать строку "Rv" (но сохранить предположение, что столбец 3 - это строка значений, разделенных запятыми), мы можем сделать следующее:
#!/usr/bin/env python
import sys
with open(sys.argv[1]) as fd:
for index,line in enumerate(fd):
columns = line.strip().split()
num_genes=len(columns[2].split(","))
print("Line "+str(index)+" contains "+str(num_genes))
Тестовый запуск:
$ ./count_genes.py input.txt
Line 0 contains 3
Line 1 contains 4
Line 2 contains 1