简体   繁体   中英

How to print lines from a file with a leading string using Perl?

I'm very new to Perl. I've started this tutorial http://www.comp.leeds.ac.uk/Perl/ . There's an exercise in the filehandling section which reads:

Modify the above program so that the entire file is printed with a # symbol at the beginning of each line. You should only have to add one line and modify another. Use the $" variable.

This is the program:

#!/usr/local/bin/perl
#
# Program to open the password file, read it in,
# print it, and close it again.

$file = '/etc/passwd';      # Name the file
open(INFO, $file);      # Open the file
@lines = <INFO>;        # Read it into an array
close(INFO);            # Close the file
print @lines;           # Print the array

Could someone help me with this very easy task? Also, what does it mean when it mentions the $" variable? Thanks in advance.

也许您应该在perldoc perlvar中查找$"变量并查看其作用。如果这样做,其余的工作就很简单。

The key to this is understanding the use of the $" variable (note: this is not the same as the $_ variable). The $" variable:

This is the separator used between list elements when an array variable is interpolated into a double-quoted string. Normally, its value is a space character.

What does this mean? It means that there is a way to convert an array of items into a string context, with each item seperated by a special character. By default, that special character is a space...but we can change what that special character is by changing the $" variable.

SPOILER ALERT

The below text contains the solution to the exercise!

SPOILER ALERT

So, the first part of this exercise is to print out the file in a string context, instead of an array. Let's pretend we have a fake file whose contents are:

[/etc/passwd]
User1
User2
User3

[exercise.pl]
#!/usr/local/bin/perl   
#   
# Program to open the password file, read it in,   
# print it, and close it again.      
$file = '/etc/passwd';      # Name the file   
open(INFO, $file);          # Open the file   
@lines = <INFO>;            # Read it into an array   
close(INFO);                # Close the file   
print "@lines";             # Print the array   <---- Notice the double quotes

[RESULT]
User1
 User2
 User3

Notice that space added in between the elements? That's because when we interpolate the array into a string context, the $" variable comes into play, and adds a space in between each element as it is concatenated. What we need to do next is change that space into a "#". We can change the $" variable before printing to do this:

[exercise.pl]
#!/usr/local/bin/perl   
#   
# Program to open the password file, read it in,   
# print it, and close it again.      
$file = '/etc/passwd';      # Name the file   
open(INFO, $file);          # Open the file   
@lines = <INFO>;            # Read it into an array   
close(INFO);                # Close the file
$" = "#";                   # Change $"         <---- This line has been added!
print "@lines";             # Print the array   <---- Notice the double quotes

[RESULT]
User1
#User2
#User3

Allright! We're almost there. The last bit is to get a "#" in front of the very first line. Because $" changes the seperator between elements, it doesn't affect the very first line! We can finish this off by changing the print statement to print a "#" followed by the contents of the file:

[exercise.pl]
#!/usr/local/bin/perl   
#   
# Program to open the password file, read it in,   
# print it, and close it again.      
$file = '/etc/passwd';      # Name the file   
open(INFO, $file);          # Open the file   
@lines = <INFO>;            # Read it into an array   
close(INFO);                # Close the file
$" = "#";                   # Change $"         <---- This line has been added!
print "#" . "@lines";       # Print the array   <---- Notice the double quotes

[RESULT]
#User1
#User2
#User3

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM