Как я могу применить Unix / Sed / Perl транслитерирует (TR) только к определенному столбцу?

Я расцениваю, они если-lseif-... создают как "шум ключевого слова". В то время как может быть ясно, что это делает, этому недостает краткости; я рассматриваю краткость как важную часть удобочитаемости. Большинство языков обеспечивает что-то как switch оператор. Создание карты является способом получить что-то подобное на языках, которые не имеют такого, но, конечно, похоже на обходное решение, и существует немного служебное (оператор переключения переводит в некоторых простых, сравнивают операции и условные переходы, но карта сначала создается в памяти, затем запросила, и только затем сравнивание и переход происходят).

В языке Common LISP, существует две встроенные конструкции переключателя, cond и case. cond позволяет произвольные условные выражения, в то время как case только тесты для равенства, но более кратко.

(cond ((= i 1)
       (do-one))
      ((= i 2)
       (do-two))
      ((= i 3)
       (do-three))
      (t
       (do-none)))

(case i (1 (do-one)) (2 (do-two)) (3 (do-three)) (otherwise (do-none)))

, Конечно, Вы могли сделать свое собственное case - как макрос для Ваших потребностей.

В Perl, можно использовать for оператор, дополнительно с произвольной маркировкой (здесь: SWITCH):

SWITCH: for ($i) {
    /1/ && do { do_one; last SWITCH; };
    /2/ && do { do_two; last SWITCH; };
    /3/ && do { do_three; last SWITCH; };
    do_none; };
5
задан brian d foy 8 October 2009 в 23:24
поделиться

2 ответа

Это должно быть возможно сделать с помощью sed, поместить это в файл (вы можете сделать это из командной строки с помощью -e, просто не забудьте эти точки с запятой или используйте отдельные -e для каждой строки). ( РЕДАКТИРОВАТЬ: Имейте в виду, поскольку ваши данные разделены табуляцией, на самом деле это должен быть символ табуляции, а не пробел в первых s //, убедитесь, что ваш редактор не превращает его в пробелы)

#!/usr/bin/sed -f

h
s/ .*$//
y/0123/ACGT/
G
s/\n[0-3]*//

и используйте

./mycode somefile | sed -f sedfile

или chmod 755 sedfile и выполните

./mycode somefile | sedfile

Выполняемые шаги:

  1. копировать буфер для хранения пространства (замена удерживаемого содержимого из предыдущей строки, если таковая имеется)
  2. удалить завершающий материал (от первого пробела до конца строки)
  3. транслитерировать
  4. добавить содержимое из удерживаемого места
  5. удалить новую строку (с шага добавления) и все цифры, следующие за ней (до пробела)

Как минимум работал у меня с вашими данными.

РЕДАКТИРОВАТЬ :
Ах, вы хотели однострочную версию ...

GNU sed

sed -e "h;s/ .*$//;y/0123/ACGT/;G;s/\n[0-3]*//"

или sed старой школы (без точек с запятой)

sed -e h -e "s/ .*$//" -e "y/0123/ACGT/" -e G -e "s/\n[0-3]*//"
7
ответ дан 18 December 2019 в 09:08
поделиться

Using Perl:

C:\> ./mycode file | perl -lpe "($x,$y)=split; $x=~tr/0123/ACGT/; $_=qq{$x\t$y}"
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA      238671
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC      0
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAG      0
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAT      0
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACA      0
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACC      1548.81
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACG      0
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACT      937.306

You can use single quotes in Bash:

  
$ ./mycode file | perl -lpe '($x,$y)=split; $x=~tr/0123/ACGT/; $_="$x\t$y"' 

As @ysth notes in the comments, perl actually provides the command line options -a and -F:

 -a                autosplit mode with -n or -p (splits $_ into @F)
 ...
 -F/pattern/       split() pattern for -a switch (//'s are optional)

Using those:

perl -lawnF'\t' -e '$,="\t"; $F[0] =~ y/0123/ACGT/; print @F'
8
ответ дан 18 December 2019 в 09:08
поделиться
Другие вопросы по тегам:

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