home | O'Reilly's CD bookshelfs | FreeBSD | Linux | Cisco | Cisco Exam  


UNIX Power Tools

UNIX Power ToolsSearch this book
Previous: 9.23 Workaround for "Arguments too long" Error Chapter 9
Saving Time on the Command Line
Next: 9.25 The C Shell repeat Command
 

9.24 Get File List by Editing Output of ls -l, grep, etc.

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.

9.24.1 What Files Have I Just Edited?

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:

  1. Make the file list and start the editor:

    
!$
     
    % ls -lt > /tmp/bk$$
    
    
    % vi !$
    
    
    vi /tmp/bk28182

  2. 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
    ...

  3. 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^

  4. 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-
    
    

  5. 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.

  6. 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$$`
    
    

  7. 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.

9.24.2 Search for Text with grep

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:

  1. 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$$
    
    

  2. 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:
       ...

  3. 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.

- JP


Previous: 9.23 Workaround for "Arguments too long" Error UNIX Power Tools Next: 9.25 The C Shell repeat Command
9.23 Workaround for "Arguments too long" Error Book Index 9.25 The C Shell repeat Command

The UNIX CD Bookshelf NavigationThe UNIX CD BookshelfUNIX Power ToolsUNIX in a NutshellLearning the vi Editorsed & awkLearning the Korn ShellLearning the UNIX Operating System