I started trying to provide comments inline in your code to explain the error messages you were seeing, the bugs that weren't showing up in the error messages, and to introduce a few best practices that don't manifest as bugs but need to be considered. But the code became illegible. So here's a few areas to focus on:
- Read perlintro, strict, perlsub, and my to gain an understanding of why you are using strict near the top of your program, and what that means to you. It's rarely a good idea to just use a line of code without knowing what it is for. Once you understand what it is for, you will quickly see the reason for many of the error messages you're seeing.
- Read open and perlopentut to understand "three-arg open, and why you should be using it. Also to understand the importance of, and how to accomplish checking the return value of system calls such as open and close. Your code actually commits the big no-no of accepting user input (via @ARGV) and then passing it through to the shell (via open IN, $ARGV[0]). If you trust the user, which may be just you anyway, it's probably not such a big deal, but if this script were ever to be invoked by a web-app, look out.
- In perlintro and perldata you can gain an understanding of the difference between Perl's different data types, or containers. A hash starts with a %, and is indexed as $hash{key}. And an array starts with a @, and is indexed as $array[index]. Declaring my @array and then later calling $array{index} is actually looking in %array for an element. They are distinct and different containers.
- Statements are delimited with a trailing semicolon. The semicolon may be omitted at the last statement in a block, and at the last statement in a program, but often are not omitted because it's just a good habit to hit that ; when your statement terminates.
- Although Perl will often let you put whitespace between the sigil and the beginning of an identifier, it's sometimes ambiguous, and always difficult for the reader of the code later on. $foo, please, not $ foo. You'll thank yourself later (or curse yourself the first time $ foo causes a difficult to find bug)
- Variables always start with a sigil. When referring to an element in an aggregate container, that sigil is $. When referring to a scalar variable that sigil is also $. When referring to an aggregate container as a whole, the sigil is @ or %, depending on the type of container. And when taking a slice of an aggregate container, the sigil is @. Disavow any knowledge of * and & for now. You'll use & later when you need it, and on rare occasion *, but for now you don't need them. ;) @ARGV also starts with a sigil, and when indexing its elements, start with $.