The immediate problem is that $file is the name of the file. You open it but never actually read anything from it.
Here are some further comments on your code
It is common practice, and much tidier, to collect the parameters of a subroutine like this
my ($id, $file) = @_
This also has the advantage of copying the values, so that the actual parameters in the call are in less danger of being modified
You should use the three-parameter form of open and lexical file handles, like this
open my $fh, '<', $file
In particular, the file is left open when the subroutine exits in your case because you have chosen a global file handle. Lexical handles are closed implicitly when they go out of scope
You should use the $! built-in variable in the open error message to give information on why it failed
An error is generally indicated by a bare return, which returns undef or an empty list, dependent on context. return 0 in list context results in the list (0) which produces a true value if it is assigned to an array
Unless you really need to be able to access all of a file at once, it is generally best to use a while loop to read and process it line by line
The /g regex match modifier is for finding all occurrences of a pattern in a string. It is unnecessary and wasteful if all you want to do is check whether the pattern appears anywhere in the string
Also your regex has a lot of problems. If I add the /x modifier then I can add spaces to show you better what you have written
/ d \s+ S+ \s \Q$id \d isk \d+ s \d+ /x
which matches
- a single
d character
- one or more space characters
- one or more
S characters
- a single space character
- The
\Q isn't terminated, so the rest of the string is matched literally. If you had \Q$id\E then the rest of the pattern would match
- a single digit
- the string
isk
- one or more digits
- a single
s character
- one or more digits
which doesn't come close to matching the record format that you show. It's important to remember that there is no need for your pattern to matc all of the string, so you may want something like just /\b\Q$id\E\b/ which checks that your ID is somewhere in the string with word boundaries at each end. I Don't see a string like 0x123456789ABC appearing elsewhere and giving a false positive
I think the best solution is to split each record on whitespace and check whether the third field matches the ID passed in
Your subroutine should look like this
sub routine {
my ($id, $file) = @_;
open my $fh, '<', $file or do {
warn "Unable to open '$file' for input: $!";
return;
};
while (my $line = <$fh>) {
my @fields = split ' ', $line;
if ($fields[2] eq $id) {
print "Yay! I found it!\n";
return 1;
}
}
return;
}
$fileis the name of the file. You open it but never actually read anything from it. And your regex doesn't take account of the size field999.9 GBin each record