Unix Basic Tutorial

Command Line Environment Searching

Thus far we've explored only a handful of files in a couple directories. Now, let's move to looking at larger amounts of files and those from which you may need specific information.

Let's say you wanted to copy all of the ".txt" files from one directory to another, but there were several different file types present in that directory. In a GUI (graphical user interface) environment, you would probably sort the file list by type/extension and then just select the desired files, which are now listed in a block. In a Unix environment, you can find, list, sort and copy all the files of one type by using wildcards. These are special characters that can be used like wild cards in a card game - they can be anything you want them to be.

Navigate to the "asm-1.9" directory under /root/dos. To list all of the .txt files only, you would enter your command as:

~/dos/asm-1.9 # ls *.txt

The wildcard in this case is the special character "*". This wildcard represents any number of characters, digits, or whitespace followed by the last 4 characters being exactly ".txt".

Question

What files would be returned from this "ls *.txt" command, based on the following list of files and directories? Select all that apply.

~/dos/asm-1.9 # ls Changelog	display.s	expr.s			lister.s	readme.txt	symtab.i asm.s		dos.i		input.s			message.s	support.s	symtab.s direct.s	equ.s		license.txt		output.s	symbols.s

The correct answers are c, d.

Any filename that ends with .txt would be returned from this command except for a file called ".txt" (without the quotes) since it doesn't have any characters, digits, punctuation marks, or whitespace before the ".".

Please make a selection.

There are many different wildcards available in Unix. Some common wildcards are:

  • * (any non-zero number of characters, digits, punctuation marks, or whitespaces)
  • ? (any single character, digit, punctuation, or whitespace)
  • [ ] (a user-defined range of characters, digits, punctuation, or whitespace that takes up one space)

Let's do some examples using wildcards.

Question

How many files would be returned by entering each of the "ls [option]" searches below?

~/dos/asm-1.9 # ls Changelog	display.s	expr.s			lister.s	readme.txt	symtab.i asm.s		dos.i		input.s			message.s	support.s	symtab.s direct.s	equ.s		license.txt		output.s	symbols.s
a) ls [a-g].s
b) ls [a-g]??.s
c) ls [a-g]*.s
d) ls *.s
e) ls *

The coded answers for each of the previous examples are below.

~/asm-1.9 # ls [a-g].s ~/asm-1.9 #
~/asm-1.9 # ls [a-g]??.s asm.s	equ.s ~/asm-1.9 #
~/asm-1.9 # ls [a-g]*.s asm.s 	direct.s	display.s	equ.s	expr.s ~/asm-1.9 #
~/asm-1.9 # ls *.s asm.s		display.s	expr.s		lister.s	output.s	symbols.s direct.s	equ.s		input.s		message.s	support.s	symtab.s ~/asm-1.9 #
~/asm-1.9 # ls * Changelog	display.s	expr.s			lister.s	readme.txt	symtab.i asm.s		dos.i		input.s			message.s	support.s	symtab.s direct.s	equ.s		license.txt		output.s	symbols.s ~/asm-1.9 #

If you wanted to list all the files that started with an A through G (capitals matter!), you could do that within a bracketed list like so:

~/dos/asm-1.9 # ls [A-G]*

This will display a file listing that returns one filename: Changelog.

If you wanted the "ls" command to return both capital and lowercase letters, you would need to include both of them within the brackets separated by a comma.

~/dos/asm-1.9 # ls [a-g,A-G]*

Using wildcards is great if you know where certain types of files are located. But what about if you don't know where a file is, but remember part of its name? You can still use wildcards, but you will need more functionality than just "ls".

Using the "find" command, you can find those missing files using wildcards. And, searches with find will search the current directory and any sub-directories. Be careful when doing this if you have a lot of sub-directories containing many files, as it can take a very long time to search all of the content.

The syntax for the find command is as follows:

find -name search_string

where -name indicates that it will search for the name of the file.

Here's an example of a find command.

~/dos # find -name 'a*' ./asm.com ./asm-1.9 ./asm-1.9/asm.s ~/dos #

Notice that the command returned both files and directories and even files in sub-directories from where the command was run. These are all the files that start with an "a" and are any length longer than just "a". So we found the files we were looking for that started with "a".

What if you didn't know the name of the file, but remembered something within the file? To find something within a file, you can use the command "grep", which stands for Global Regular Expression Print. Grep follows the syntax below:

grep search_expression file_to_search

As an example, let's search through the file hello.c within your home directory to see if it contains the string "int".

/root # grep int hello.c int main(int, argc, char **argv)   printf("Hello World\n"); /root #

Grep found two instances of that string. Notice though that the lines that are returned aren't looking for the word "int", they are looking for the string "int", which can be inside a word. This is the reason that "printf" is returned in the example - it contains "int" inside the word.

If you wanted to only return instances where the pattern was a word, you can add the "-w" option after grep.

/root # grep -w int hello.c int main(int, argc, char **argv) /root #

What if you didn't know the name of the file that had the string within it? You could still find all the files that contain that string with grep but you could use a wildcard in place of the "file_to_search".

Let's say we wanted to search for ALL files below your dos directory that contained the string "print". The following code would show you those files and print the lines which have the "print" pattern on them. The added code here is the "-r" option which digs recursively downward from your current directory giving the results below.

~/dos # grep -r print * asm-1.9/readme.txt:The contents of the symbol table are printed out at the end o f the asm-1.9/readme.txt:Only one of -x or -z must be specified.  The -x option prints  a asm-1.9/readme.txt:complete xref dump (definitions + references) The -z option p rints a asm-1.9/readme.txt:To print labels not referenced asm-1.9/readme.txt:To print all defined symbols: asm-1.9/readme.txt:To print crossreferences: asm-1.9/message.s:|  BX points to the message to be printed asm-1.9/message.s:|The procedure print 'asm :', the message, a carriage return a nd a line feed asm-1.9/lister.s:|Lister - print the symbol table of the assembler from the list  file. asm-1.9/Changelog:1. Instead of printing the symbol table onto the screen it put s asm-1.9/Changelog:7. A separate program lister was added which prints out the sy mbol asm-1.9/Changelog:2. The print stats function was removed asm-1.9/Changelog:7. Doesn't print the name of the file that it is assembling an y longer. asm-1.9/equ.s:  call SprintRegister asm-1.9/symtab.s:  call SprintRegister asm-1.9/symtab.s:SprintRegister: asm-1.9/symtab.s:SprintRegisterMore: asm-1.9/symtab.s:  call SprintHexDigit asm-1.9/symtab.s:  jnz  SprintRegisterMore asm-1.9/symtab.s:SprintHexDigit: ~/dos #

Command

Description

Usage

find

Find files recursively by their file name and list them.

find -name string_or_wildcard

grep

Find files by their contents and display the line from each file that contains that search string.

grep search_string file

Wildcard

Description

Example

*

any non-zero number of characters, digits, punctuation marks, or whitespaces

ls *.jpg

ls file*

ls *in*

?

any single character, digit, punctuation mark, or whitespace

ls photo?.jpg

ls ?ilename.txt

ls test?file.txt

[...]

A user-defined range of characters, digits, punctuation, or whitespace that takes up one space

ls file[0-9].jpg

ls [a-z]ile.txt

ls file[_, ,.]name.txt