再次提出一些问题。我有一个表格的文件:
>seq1
123 234 56
167 332 22
23 456 098
>seq2
123 234 56
167 332 22
23 456 098
我希望每个> seq#都保存一个文件,如下所示:
文件1:
>seq1
123 234 56
167 332 22
23 456 098
文件2:
>seq2
123 234 56
167 332 22
23 456 098
我可以使用perl脚本但是想知道如何使用perl单行程来完成,只是为了增加我的perl知识。
谢谢!
答案 0 :(得分:2)
这是一个完成工作的相当小的脚本:
use strict;
use warnings;
my $fh = *STDOUT;
while (<>)
{
chomp;
if (m/^>/)
{
close $fh;
open $fh, $_ or die "Failed to open $_";
}
print $fh "$_\n";
}
my $fh = *STDOUT;
行表示如果第一行>file
行之前有内容,则会回显标准输出。
以此为基础,您可以决定将其展平为一行,忽略错误,关闭打开的文件,限制和可读性:
perl -e 'while(<>){chomp;open$f,$_ if(m/^>/);print$f "$_\n";}'
但是,我不太可能推荐这个。 (是的,两个空白都是必要的。)
答案 1 :(得分:2)
看着Jonathan's answer,我想出了一些奇怪的东西,可以发布一个新答案。我想补充一点,这应该被视为一个练习示例(可能是混淆),而不是任何正确的代码。完全归功于Jonathan的解决方案。此外,这是一个危险的解决方案,如底部所述。
perl -ple 'open STDOUT, $_' yourfile.txt
这取决于以>seq1
开头的行与Jonathan发现的旧2参数open
一起使用。例如。 open $fh, ">seq1"
将创建(覆盖)并打开文件seq1
进行写入。
同时,任何没有有效“模式”符号的行 - <
,>
,|
等 - 都会默认打开以供阅读如果我们在该目录中不存在名称为123 234 56
等的文件的事实,我们可以依赖我们的open
静默失败并维护以前打开的STDOUT
文件句柄
使用-l
选项,我们无需chomp
$_
,因此open
不会失败,我们也不需要添加换行符打印。同时,-p
选项将负责创建while
循环并进行打印。
因为默认情况下打印到STDOUT
,所以我们需要做的就是重新打开STDOUT
文件句柄,输入文件的内容负责其余部分。
这个单行的完整代码,带有注释,表示哪些部分来自哪个开关:
BEGIN { $/ = "\n"; $\ = "\n"; } # -l, gives newlines to print
while (<>) { # -p
chomp $_; # -l
open STDOUT, $_; # our code
}
continue {
print STDOUT $_; # -p
}
注意:此代码将释放open
命令的全部功能,这样做很危险,在这种情况下,允许在文件系统上执行任意命令。这是允许使用2参数打开的副作用。