So far we've been working with data that is provided by a user inputting text. However more often than not we actually work with data that has been saved to the server. There are many ways data can be saved to the server, including SQL databases, but we're going to work with the most common and basic, text files. # Text File Formats There are two main types of text file formats; separated-value formats and data-structure formats. Separate-value formats use a specific character to separate the important information, such as commas (CSV files). The limitation is that you cannot use that character in any of your data without escaping it, and that is a lot of coding, so most coders will use a character that is seldom used. Mr. Windsor's favourite is the vertical line (usually above the Enter key on a computer). CSV: ``` csv first_name,Joel last_name,Windsor ``` Vertical-Line Separated: ``` first_name|Joel last_name|Windsor ``` You can of course have many "columns", but the challenge is that you will need to remember what those columns are for, because you cannot include titles in the data file. ``` Joel|Windsor|January|12|2012 Bill|Gates|April|17|1982 ``` Somewhere you would have to keep track of what those dates mean, because they certainly aren't birthdates! The other format type is data-structure formats, a format where a predefined structure is already available. The most common one is JavaScript Object Notation, or JSON. The benefit of JSON is that it is already in a format that PERL can easily convert into hashes and arrays. ``` json { [ "first_name" : "Joel", "last_name" : "Windsor", "created" : { "month" : "January", "day" : 12, "year" : 2012 } ] } ``` JSON and other data-structure formats have the benefit of being very clear and easy to understand. However bringing it into PERL usually requires a helper module. So for now, we'll be focusing on the absolute basics of reading separated-value files. # Reading Text Files You're used to getting data from `STDIN`. That is the Standard Input data handle. We're going to create a file handle instead and we'll put it into a *scalar* called `$fh`. We're going to open it in *read* mode, meaning we will not be able to edit the file ... yet. Then we're going to save the data we read from that file handle into another *scalar*, then close the file so that it can be used again in the future. ``` perl open $fh, '<', 'data/mydata.txt'; $filecontents = <$fh>; close $fh; ``` If we were to read the comma-separated-value file that included only Mr. Windsor's first and last names, `$filecontents` would have the following in it: `first_name,Joel\nlast_name,Windsor\n` We can also get Perl to automatically split it into an array of every file line as follows; ``` perl open $fh, '<', 'data/mydata.txt'; @filelines = <$fh>; close $fh; ``` and `@filelines` will include; ``` first_name,Joel\n last_name,Windsor\n ``` Then you can use a `for` loop with `chomp` to get rid of all the newlines, and `split`. ``` perl my %DATA; for $line (@filelines) { chomp($line); ($key, $value) = split(',', $line); $DATA{$key} = $value; } ``` Now you can work with your data. # Assignment Mr. Windsor will provide you with a file. He will only tell you the file format. Your task will be to read the file, collect an input from STDIN, and use that input to print *only* the information that matches. ## Example output ``` bash Choose either first, last or middle by typing it here: middle Jacob John Thomas Sarah Vincent Terry ``` The above input suggests that the file you read from must have a first, last and middle value, but you are only printing the middle ones because that is what the user entered.