使用特定字符串和不同的数字和字母创建序列

使用特定字符串和不同的数字和字母创建序列

我需要创建一行,其中的列具有共享字符串、数字不同且共享重复字母。我想要的输出如下:

SNP1a  SNP1b  SNP2a  SNP2b ... SNP3502a  SNP3502b

我是 unix/linux 的新手,所以我的尝试相当初级。到目前为止我已经做了:

seq -f "SNP%1g" 1 3502 > header
awk '{print;print;}' header > header2

所以那header2就是:

SNP1
SNP1
SNP2
SNP2
...
SNP3502
SNP3502

但是,我对如何向每一行添加交替的a和感到困惑。b

任何帮助将不胜感激!

答案1

带壳zsh

() { print ${(j[  ])@}; } SNP{1..3502}{a,b}

在哪里:

  • SNP{1..3502}{a,b}使用大括号扩展生成列表
  • 它被传递给匿名函数,其中列表在$@又名$argv数组中可用
  • j[ ]我们使用参数扩展标志将数组的元素连接起来,中间有两个空格
  • 并将其传递给print打印它的人。

从另一个外壳:

zsh -c '() { print ${(j[  ])@}; } SNP{1..3502}{a,b}'

如果您的数字列表、前缀和后缀位于单独的数组中:

pre=( SNP )
num=( {1..3502} )
suf=( a b )
() { print ${(j[  ])@}; } $^pre$^num$^suf

perl

perl -le 'print join "  ", map {$n=$_; map "SNP$n$_", qw(a b)} (1..3502)'

答案2

对于 ksh、bash 或 zsh 中的任何一个,只需使用 echo:

$ echo SNP{1..3502}{a,b}       # {a..b} also works here.
SNP1a SNP1b SNP2a SNP2b SNP3a SNP3b SNP4a SNP4b SNP5a .....

在这种特定情况下,echo完全没问题,因为生成的列表上没有前导“-”,内部也没有特殊字符。

如果您必须使用printf,请尝试:

printf '%s\n' SNP{1..3}{a,b} | paste -s -d ' ' -

并且,如果您必须使用 awk,那么使用艾德·莫顿的回答

答案3

bash

printf '%s ' SNP{1..3502}{a..b}

如果最后一个尾随空格有问题,请将其包装在函数中:

headers(){
    local pieces=( SNP{1..3052}{a..b} ) IFS=' '
    printf '%s' "${pieces[*]}" # add '\n' to get new line at the end
}

答案4

使用(以前称为 Perl_6)

raku -e 'my  @nbr = "SNP" xx 3502 Z~ 1..3502; \
         for @nbr -> $i {put $i ~ "a"; put $i ~ "b"};'   

或者

raku -e 'my @nbr = "SNP" xx 3502 Z~ 1..3502; my @ltr = "a".."b"; \
         for @nbr -> $i {put $i ~ @ltr[0]; put $i ~ @ltr[1]};'  

或者

raku -e 'my @nbr = "SNP" xx 3502 Z~ 1..3502; my @ltr = "a".."b"; \
         for @nbr -> $i {put $i ~ $_ for @ltr};' 

毫无疑问,这可以改进,但它已经完成了工作。该代码使用 Raku 的Z 中缀运算符,与 Raku 的~(波形符)字符串连接运算符结合使用。每个标识符打印在单独的行上。在第三个示例中,@ltr字母加载到$_(又名 Raku 的主题变量)中。

有关如何在 Raku 中创建标识符字符串序列的更多想法,请参阅下面的 SO 链接:

https://stackoverflow.com/questions/47999523/concatenating-lists-in-raku

相关内容