我需要创建一行,其中的列具有共享字符串、数字不同且共享重复字母。我想要的输出如下:
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?