我写了以下脚本:
#!/usr/bin/perl -w
use strict;
die "usage:$0 <Input_folder_1>\t<Input_folder_2>\t<Out_folder>\t<Project_name>\t\n" unless $#ARGV == 3;
my $folder1 = shift;
#print "$folder1\n";
my $folder2 = shift;
#print "$folder2\n";
my $out = shift;
my $project_name = shift;
my $file1;
my $file2;
my $file3;
my $file4;
#print "$project_name\n";
foreach(glob("$folder1/$project_name\_S[0-9]_R1_001.fastq.gz")){
chomp;
#print "Hello World\n";
$_ =~ m{$folder1/$project_name\_S[0-9]_R1_001\.fastq.gz};
#print "$_\n";
$file1 = $_;
print "$file1\n";
}
foreach(glob("$folder2/$project_name\_S[0-9]_R1_001.fastq.gz")){
chomp;
#print "Hello World\n";
$_ =~ m{$folder2/$project_name\_S[0-9]_R1_001\.fastq.gz};
#print "$_\n";
$file2 = $_;
print "$file2\n";
}
cat $file1 $file2 > $out/$project_name.R1.fastq.gz
; #line 42
foreach(glob("$folder1/$project_name\_S[0-9]_R2_001.fastq.gz")){
chomp;
#print "Hello World\n";
$_ =~ m{$folder1/$project_name\_S[0-9]_R2_001\.fastq.gz};
#print "$_\n";
$file3 = $_;
print "$file3\n";
}
foreach(glob("$folder2/$project_name\_S[0-9]_R2_001.fastq.gz")){
chomp;
#print "Hello World\n";
$_ =~ m{$folder2/$project_name\_S[0-9]_R2_001\.fastq.gz};
#print "$_\n";
$file4 = $_;
print "$file4\n";
}
`cat $file3 $file4 > $out/$project_name.R2.fastq.gz`;
该脚本运行如下:
./script.pl folder1 folder2 output_folder project_name
当我使用以下文件运行此脚本时,它运行顺利
folder1/123-abcQ_S3_R1_001.fastq.gz
folder2/123-abcQ_S1_R1_001.fastq.gz
folder1/123-abcQ_S3_R2_001.fastq.gz
folder2/123-abcQ_S1_R2_001.fastq.gz
./script.pl folder1 folder2 out/ 123-abcQ
它将合并文件folder1 / 123-abcQ_S3_R1_001.fastq.gz和folder2 / 123-abcQ_S1_R1_001.fastq.gz,以在输出目录中创建合并的123-abcQ.R1.fastq.gz文件。
但是,当我使用以下文件运行相同的脚本时,它会给我一个错误:
folder1/demo-1_S10_R1_001.fastq.gz
folder1/demo-1_S10_R2_001.fastq.gz
folder2/demo-1_S12_R1_001.fastq.gz
folder2/demo-1_S12_R2_001.fastq.gz
./script.pl folder1 folder2 out/ demo-1
在连接(。)中使用未初始化的值$ file1或在./script.pl第42行使用字符串。在连接(。)中使用未初始化的值$ file2或在./script.pl第42行使用字符串。
我无法弄清楚如何解决这个问题。您的建议将不胜感激。
使用第二组参数,您不应在警告之前看到任何输出。它不打印任何东西。
那是因为它不会从你的glob
调用中返回任何文件,所以foreach
循环实际上并没有被执行。 $file1
最初是undef
,现在永远不会被设定。
my $file1; # starts out as undef
# ...
#print "$project_name\n";
foreach(glob("$folder1/$project_name\_S[0-9]_R1_001.fastq.gz")){ # finds nothing
chomp;
#print "Hello World\n";
$_ =~ m{$folder1/$project_name\_S[0-9]_R1_001\.fastq.gz};
#print "$_\n";
$file1 = $_;
print "$file1\n"; # no output here
}
它可能找不到您的文件,因为您没有任何与该模式匹配的文件。
这里有两件事:
glob
采取可以包含a sort of pattern的wildcards。它只返回与此模式匹配的文件。它不是正则表达式*。让我们更仔细地看一下。
foreach(glob("$folder1/$project_name\_S[0-9]_R2_001.fastq.gz")){
有趣的是glob EXPR
。你的表达是:
# | variable interpolation
# | | variable interpolation
# | | | treat this as a literal underscore, not part of var name
# | | | one digit out of group 0, 1, 2, 3, 4, 5, 6, 7, 8, 9
# | | | | |
$folder1/$project_name\_S[0-9]_R2_001.fastq.gz
这将返回与此模式匹配的文件列表。如果没有找到任何文件,则不返回任何内容。然后foreach
循环迭代该列表。同样,如果列表中没有任何内容,则永远不会调用循环。
foreach ( glob ... ) { chomp; $_ =~ m{$folder1/$project_name\_S[0-9]_R1_001\.fastq.gz}; $file1 = $_;
你现在用chomp
切断了换行符。这没有任何意义,因为文件名通常最后没有换行符。
然后,您使用与glob
相同的模式对文件名进行模式匹配。在这种情况下,它是一个实际的正则表达式,因此某些字符具有特殊含义。
m{
$folder1 # variable interpolation
/ # literal slash /
$project_name # variable interpolation
\_S # literal backslash \ and S
[0-9] # one digit from 0 to 9
_R1_001 # literal string
\. # literal dot .
fastq # literal string
. # exactly one of any character
gz # literal string
};
如您所见,该模式意味着完全不同的东西。你逃脱了其中一个点.
,但不是两个。
但这没关系,因为这个操作没有做任何事情。你只是扔掉了结果!
然后你将$_
分配给$file1
,无论是否匹配。
我认为只需获取该目录中的所有gzip压缩文件然后检查它们就更有意义了。
foreach my $filename ( glob <$folder1/${project_name}*.fastq.gz> ) {
if ( $filename =~ m{
/ # separates the folder from the filename
$project_name # anchor to project
_
[0-9]+ # one or more numbers (001, 123, 9, ...)
_R1_001
\.fastq\.gz # file type
$ # end of string
}x
) {
$file1 = $filename;
last;
}
}
这使用其他glob
语法,我发现它更具可读性,获取$folder1
中以$project_name
开头并以.fastq.gz
结尾的所有文件。然后它迭代文件列表并执行模式匹配,以确保我们实际获得正确的文件。我已经包含了/x
修饰符来忽略模式中的空格,所以我们可以有注释。
请注意[0-9]+
,它表示一个或多个数字。这很重要,因此可以找到数字大于9的文件。
找到匹配后,它会分配$file1
,然后使用last
退出循环。
在运行使用$file1
和$file2
的外部命令之前,您可能还想添加一个检查。
if ($file1 && $file2) {
`cat $file1 $file2 > $out/$project_name.R1.fastq.gz`
} else {
print "No matches found for first set of files.";
}