The code I wrote is as below :
#!/usr/bin/perl
my @input = ( \"a.txt\" , \"b.txt\" , \"c.txt\" ) ;
my @output = map { $_ =~ s/\\..*$// } @input ;
print @o
The problem of $_ aliasing the list's values was already discussed.
But what's more: Your question's title clearly says "map", but your code uses grep, although it looks like it really should use map.
grep will evaluate each element in the list you provide as a second argument. And in list context it will return a list consisting of those elements of the original list for which your expression returned true.
map on the other hand uses the expression or block argument to transform the elements of the list argument returning a new list consisting of the transformed arguments of the original.
Thus your problem could be solved with code like this:
@output = map { m/(.+)\.[^\.]+/ ? $1 : $_ } @input;
This will match the part of the file name that is not an extension and return it as a result of the evaluation or return the original name if there is no extension.