Project 63. Editing Tips"How do I format and embellish the output from my scripts?" Learn More
This project gives you some handy tips for editing files with commands not covered elsewhere in this chapter. Edit with echoThe echo command provides a quick and easy way of adding a line of text to the end of an existing text file, or creating a new one-line file, without having to use a text editor. For example, to stop Terminal from beeping (see Project 45), add the appropriate line to ~/.inputrc as follows. $ echo "set bell-style none" >> ~/.inputrc It's important to use a double redirect symbol (>>), not a single one (>), when redirecting output to an existing file. The double redirect appends to the target file, whereas the single redirect creates a new file that overwrites any existing file of the same name. Edit with catUsing echo is fine for creating single-line files, but if you need to create a few-line file quickly, try the cat command instead. In the absence of an input filename, cat reads from the keyboard. Type the following, and finish by pressing Control-d to create a small file called jan.txt. $ cat > jan.txt Dear Janet, Just a quickie to let you know I'll be free... Adrian<Control-d> Edit with printfTake advantage of the formatting capabilities of the printf command to create a file with consistently formatted lines. The printf command uses a format string, which is a sequence of characters that will be displayed onscreen, interspersed with special placeholder sequences like %s. Following the format string, we must provide a value for each placeholder sequence. We can take advantage of a neat feature of printf. If the number of arguments exceeds the number of placeholders, printf takes another sweep at the format string. Let's illustrate this by using printf to create an HTML table. We'll write a format string that expects two values and surround the %s placeholders with appropriate HTML tags. Type the following command, providing six values, and you'll see that printf takes three sweeps at the format string. $ printf "<tr>\n <td>%s</td>\n <td>%s</td>\n</tr>\n" ¬ one 1 two 2 three 3 <tr> <td>one</td> <td>1</td> </tr> <tr> <td>two</td> <td>2</td> </tr> <tr> <td>three</td> <td>3</td> </tr> The character sequence \n tells printf to print a Newline. We'll extend the example, employing a barrel-load of tricks to convert the output from the ls command to an HTML table. The table shows the filenames and sizes of all text files in the current directory. First, instead of typing values on the command line, we generate them automatically by executing the command $(ls -l *.txt | awk '{print $9, $5}') This generates a long directory listing, using the awk command to filter fields 9 (the filename) and 5 (the file size). Surrounding the command with $(...) tells Bash to execute it and write the output back to the command line. The output from this command becomes the arguments to the main printf command. Additional printf commands before and after print HTML table tags. All output is redirected to the file list.html. Note that the entire sequence is encapsulated within (...) before the output is redirected. This is necessary; otherwise, the redirection is applied to only the last command. $ ( printf "<table border='1'>\n"; > printf "<tr>\n <th>Filename</th>\n <th>¬ Size</th>\n</tr>\n" > printf "<tr>\n <td>%s</td>\n <td>%s</td>\n</tr>\n" ¬ $(ls -l *.txt | awk '{print $9, $5}') > printf "</table>\n") >list.html Let's examine the file that this command generates. $ cat list.html <table border='1'> <tr> <th>Filename</th> <th>Size</th> </tr> ... <tr> <td>jan.txt</td> <td>66</td> </tr> <tr> <td>sophie.txt</td> <td>348</td> </tr> </table> That's a pretty nifty way to generate an HTML table from a directory listing, but let's take it further. Here's a Bash function that creates HTML tables. It builds on what we have already done, additionally assigning the command sequence to a function that takes three parameters (in this order): our output filename, the first table header, and the second table header. If you are familiar with Bash functions and simple scripting, check it out. $ htmltable () { > filename="$1"; shift; > h1=$1; h2=$2; shift; shift > (printf "<table border='1'>\n" > printf "<tr>\n <th>$h1</th>\n <th>$h2</th>\n</tr>\n" > printf "<tr>\n <td>%s</td>\n <td>%s</td>\n</tr>\n" $* > printf "</table>\n") > $filename > } Learn More
Let's use the function to build a table of ages, which are read from the file ages. $ cat ages Jan 27 Sophie 31 Jill 32 $ htmltable ages.html Name Age $(cat ages) $ cat ages.html <table border='1'> <tr> <th>Name</th> <th>Age</th> </tr> <tr> <td>Jan</td> <td>27</td> </tr> <tr> <td>Sophie</td> <td>31</td></tr> <tr> <td>Jill</td> <td>32</td> </tr> </table> $ Figure 7.1 shows how the table may look in a browser. Figure 7.1. A function built around the printf command generated this HTML table, displayed here in Safari.
Edit with splitThe split command breaks a large file into multiple smaller ones. To split big-file.txt into multiple files, each no bigger than 5KB, type $ split -b5k big-file.txt The resulting small files are named like this. $ ls x* xaa xab xac xad xae xaf xag xah To split a file limiting size by lines instead of bytes, type $ split -l200 big-file.txt split_ The final argument, split_, tells split to replace the x prefix assumed in the previous example with split_ when naming the output files. Edit with pasteThe paste command merges two files line by line. Here's an example to illustrate it. $ cat f1 Line 1 Line 2 ... $ cat f2 rest of line 1 rest of line 2 ... $ paste f1 f2 Line 1 rest of line 1 Line 2 rest of line 2 ... Learn More
|