|
Chapter 9 Saving Time on the Command Line
|
|
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:
!$
|
% ls -lt > /tmp/bk$$
% vi !$
vi /tmp/bk28182
|
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.
|
|