It seems like I'm always using ls -also, usually, -l and maybe other options - to find out which of my files I need to do something to. I also use grep or one of the other grep s ( 27.1 ) to search for files that have certain text in them. No matter what command I use, I redirect the output ( 13.1 ) to a temporary file ( 21.2 , 21.3 ) and then edit the file. After the editing, I have a list of filenames that I can use inside backquotes ( 9.16 ) with some other command - or store in a shell variable ( 6.8 ) .
Here are two examples. These show the vi editor, but you can use any other UNIX editor that handles plain text files. Depending on what you need, there are probably UNIX utilities that can help.
While I was working on this book, my current directory could have around 1000 files. If I wanted to find out which files I'd edited today, I would use ls -lt ( 16.2 ) to get a listing of files with the most recently modified listed first. Edit the file, delete all lines except files I'd edited today, then remove everything from each line except the filename. Finally, use backquotes and rcp ( 1.33 ) to copy the files to the ptbackup directory on the fserver computer:
Make the file list and start the editor:
!$ |
% |
---|
Delete all lines except the ones for files from February 29:
total 4294 << delete -rw-r--r-- 1 jerry 1529 Feb 29 17:25 a7630 -rw-r--r-- 1 jerry 1864 Feb 29 16:29 a0147 ... Keep these lines ... -rw-r--r-- 1 jerry 1772 Feb 29 09:01 a1900 -rw-r--r-- 1 jerry 2693 Feb 29 08:51 a0031 -rw-r--r-- 1 jerry 744 Feb 28 23:35 a7600 << delete -rw-r--r-- 1 jerry 1957 Feb 28 22:18 a5210 << delete ... Delete the rest ...
In
vi
, use the
|
(vertical bar) command (
30.34
)
to find the column number just before the filenames start. For example, here's where the commands
30|
,
39|
, and
45|
moved the cursor:
-rw-r--r-- 1 jerry 1529 Feb 29 17:25 a7630 30^ 39^ 45^
So, I want to delete columns 1-45 from every line. The easiest way is a filter-through ( 30.22 ) with colrm 1 45 ( 35.15 ) or cut -c46- ( 35.14 ) :
:%!cut -c46-
Now the file looks like this - just the filenames:
a7630 a0147 ... a1900 a0031
I can sort it with
:%!sort
if I want to - or do more editing. Then I write the file and quit.
Feed the list of filenames to the UNIX command I want to run:
%rcp `cat /tmp/bk$$` fserver:ptbackup
This works with most any UNIX command - not just rcp . For example, if I want to print the files, I can use:
%lpr `cat /tmp/bk$$`
If I'll be doing a lot of work with the filenames, typing the backquotes over and over is a pain. I'll store the filenames in a shell variable ( 6.8 ) :
First, pick a name for the shell variable. I usually choose
temp
because it's not used on my account. You should check the name you choose before you set it by typing
echo
"$
varname
"
; be sure it's empty or useless.
Store the filenames from your temporary file:
%set temp=(`cat /tmp/bk$$`)
...C shells $temp="`cat /tmp/bk$$`"
...Bourne shells
Use the shell variable. For example:
%cp $temp
backupdir
%vi $temp
% ...
(Sometimes, find with operators like -newer ( 17.8 ) is easier - but find searches subdirectories too, unless you use -prune ( 17.23 ) .) Oh, try to remember to rm the temp file when you're done with it.
The grep -l option ( 15.7 ) gives you a list of filenames that match a string - that might be all I need. But sometimes I need to see the lines that grep found to decide whether to include that file or not. Here's how:
Search the files. Be sure that your grep -like command will print the filename before each matching line:
%egrep -i "summar(y|ies)" * > /tmp/bk$$
Edit the temporary file. The lines will look something like this:
a0066:Here is a summary of the different components: a0183:Summary: String functions in awk a0183:for a summary of all the string functions a0184:Let's start wlth a short summary how awk treats command a1000:Here's a summary of the rules that UNIX uses to interpret paths: a1000:Here's a summary of the different sorts of wildcards available: a1680:cumulative summary files and ASCII reports in a2710:In summary, \fIcomm\fP is similar to \fIdiff\fP: ...
Leave a line for each file that you want to operate on; delete the rest:
a0066:Here is a summary of the different components: a0183:Summary: String functions in awk a1000:Here's a summary of the different sorts of wildcards available: ...
Strip off everything after the filenames. Unless any of your filenames have colons (
:
) in them, you can tell
vi
to strip off the colons and everything after them. That command is:
:%s/:.*//
If there's a chance that a filename might be repeated (because grep matched more than one line), filter the filenames through sort -u to get rid of duplicates. In vi , type:
:%!sort -u
Like before, what's left is a list of filenames:
a0066 a0183 a1000 ...
You can feed them to whatever command you need to run, as in the previous example.
I hope those two examples give you the idea, which is: learn what UNIX utilities are "out there"-and how to grab and edit their output to do what you want.
-