## 20.6. Change Many Files by Editing Just One

Go to http://examples.oreilly.com/upt3 for more information on: diff

The diff command can make an editing script that you give to the ex or ed editors or the patch (Section 20.9) program. They'll apply your same edits to other copies of the same file. This is handy if you have a lot of copies of a big file, spread around a network or on a lot of disks, and you want to make the same changes to all the

Section 20.8

files. In fact, this is how the Concurrent Version Control (CVS) system works. Instead of sending new copies of the whole file, just have diff make a script -- and use that little script to update all the big files.

Here's a demo. I'm going to modify a program called pqs.c. Then I'll use diff and ed to apply the same changes to a copy of the file named remote-pqs.c (which might be at a remote computer):

`>>` Section 43.1

>     1% cp pqs.c remote-pqs.c
>     2% cp pqs.c pqs.c.new
>     3% vi pqs.c.new
>     4% diff pqs.c pqs.c.new
>     106,107c106
>     <       fprintf(stderr,
>     <           "%s: quitting: not able to %s your .pq_profile file.\n",
>     --
>     >       fprintf(stderr, "%s: quitting: can't %s your .pq_profile file.\n",
>     390a390
>     >               "WARNING:",
>     5% diff -e pqs.c pqs.c.new > edscr
>     6% cat edscr
>     390a
>                     "WARNING:",
>     .
>     106,107c
>             fprintf(stderr, "%s: quitting: can't %s your .pq_profile file.\n",
>     .
>     7% echo w >> edscr
>     8% ed remote-pqs.c < edscr
>     19176
>     19184
>     9% diff pqs.c.new remote-pqs.c
>     10%

At prompt `1%`, I make the simulated "remote" copy of the pqs.c file. At prompt `2%`, I make another copy of it; at prompt `3%`, I edit the copy. Prompt `4%` has a diff that shows the changes I made. Then, at prompt `5%`, I run diff -e (Section 11.1); I save the result in edscr, which I show at prompt `6%`.

Prompt `7%` is important because diff -e doesn't add a `w` command to the script file. That tells ed to write its changes to the file. I use echo w (Section 27.5) to add the command.

In prompt `8%`, I give ed the name of the "remote" file to edit as a command-line argument and give it the script file on its standard input. At prompt `9%`, I do a diff that shows the changes have been made and the two versions are the same.

If you find yourself needing to keep multiple copies of the same set of files in sync with each other, you might want to consider using CVS. Not only is it a client/server system ready for network use, it is also designed for multiple users. Every check-in is logged, and updating a whole set of files (called "projects") can be done with the command `cvs update`. This can be a great timesaver for webmasters maintaining multiple web servers with static (or even dynamic) content.

Another great tool for synchronizing many filesystems is rsync. This program can be used to update a remote filesystem, say a web directory, with more current version of existing files or add new ones. The synchronization can go both ways. rsync even has built-in support for SSH. Here's an example of using rsync to publish new web documents to a live server:

>     $ rsync -urz -e /path/to/ssh local_dir hostname:/path/to/web/docs

The `-u` flag tells rsync to update the remote filesystem with newer files on the local system. The `-r` flag tells rsync to recurse into subdirectories. The `-z` allows the files to be gzipped during transfer (good for slow modem links). While it can be a client/server system, rsync can work just fine as a peer-to-peer system where it will need to run some commands on the remote machine. The `-e` flag provides the path to the rsh or ssh program that you to have rsync use. The next argument is the directory on the local machine rsync is to copy, and the last argument is the hostname and target directory to be updated. rsync is a very handy tool, and the manpage illustrates its flexibility.

-- JP

Copyright © 2003 O'Reilly & Associates. All rights reserved.