我写了以下脚本:
#!/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和文件夹2 / 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行的字符串。
我不知道该如何解决。您的单位将不胜感激。
答案 0 :(得分:-1)
使用第二组参数,在警告之前您不会看到任何输出。它不会打印任何内容。
那是因为它不会从您的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
,无论是否匹配。
我认为将所有压缩文件放到该目录中然后检查它们会更有意义。
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.";
}