Filename Wildcards
* acts as a match for any number and sequence of characters
? acts as a match for any single character
$ ls -d v* directory
$ ls *a contents
$ echo *
$ echo v*
$ echo 'hello world'
Advanced Filename Wildcards
character range:
$ ls -ld [abkost]*
$ ls -ld [a-z]*
search for all files that contain a single digit, dot, or underscore in the name
$ ls *[0-9._]*
Creating Sophisticated Regular Expressions
Summary of regular-expression notation.
Notation Meaning
c Matches the character c
/c Forces c to be read as the letter c, not as another meaning the character might have
^ Beginning of the line
$ End of the line
. Any single character
[xy] Any single character in the set specified
[^xy] Any single character not in the set specified
c* Zero or more occurrences of character c
$ grep miscall /etc/passwd
$ grep ^miscall /etc/passwd
$ grep "^miscall[a-z]" /etc/passwd
$ grep '^miscall[^a-z]' /etc/passwd
$ grep z* /etc/passwd|head
is identical to
$ head /etc/passwd
$ grep ':$' /etc/passwd
$ grep '$100*' * */*
* expands your search beyond files in the current directory
*/* expands your search to all files contained one directory below the current point
$ grep '. ' file
$ grep '/. ' file
Searching Files Using grep
The most helpful grep flags.
Flag Function
-c List a count of matching lines only.
-i Ignore the case of the letters in the pattern.
-l List filenames of files that match the specified pattern only.
-n Include line numbers.
For Complex Expressions, Try egrep
Regular expression notation for egrep.
Notation Meaning
c Matches the character c
/c Forces c to be read as the letter c, not as another meaning the character might have
^ Beginning of the line
$ End of the line
. Any single character
[xy] Any single character in the set specified
[^xy] Any single character not in the set specified
c* Zero or more occurrences of character c
c+ One or more occurrences of character c
c? Zero or one occurrences of character c
a|b Either a or b
(a) Regular expression
$ egrep '(z|q)' /etc/passwd | head
$ egrep '(^[a-zA-Z]|:wi)' /etc/printcap | head
Any time you want to look for lines that contain more than a single pattern, egrep is the best command to use.
Searching for Multiple Patterns at Once with fgrep
Changing Things En Route with sed
The general format of the substitution command is: s/old/new/flags, where old and new are the patterns you’re working with, s is the abbreviation for the substitute command, and the two most helpful flags are:
g (to replace all occurrences globally on each line)
n (to tell sed to replace only the first n occurrences of the pattern).
$ grep taylor /etc/passwd | sed -e 's/:/ /'
taylorj ?:1048:1375:James Taylor:/users/taylorj:/bin/csh
mtaylor ?:769:1375:Mary Taylor:/users/mtaylor:/usr/local/bin/tcsh
dataylor ?:375:518:Dave Taylor,,,,:/users/dataylor:/usr/local/lib/msh
taylorjr ?:203:1022:James Taylor:/users/taylorjr:/bin/csh
taylorrj ?:662:1042:Robert Taylor:/users/taylorrj:/bin/csh
taylorm ?:869:1508:Melanie Taylor:/users/taylorm:/bin/csh
taylor ?:1989:1412:Dave Taylor:/users/taylor:/bin/csh
$ grep taylor /etc/passwd | sed -e 's/:/ /g'
taylorj ? 1048 1375 James Taylor /users/taylorj /bin/csh
mtaylor ? 769 1375 Mary Taylor /users/mtaylor /usr/local/bin/tcsh
dataylor ? 375 518 Dave Taylor /users/dataylor /usr/local/lib/msh
taylorjr ? 203 1022 James Taylor /users/taylorjr /bin/csh
taylorrj ? 662 1042 Robert Taylor /users/taylorrj /bin/csh
taylorm ? 869 1508 Melanie Taylor /users/taylorm /bin/csh
taylor ? 1989 1412 Dave Taylor /users/taylor /bin/csh
$ grep taylor /etc/passwd | sed -e 's/Taylor/Tailor/g'
taylorj:?:1048:1375:James Tailor:/users/taylorj:/bin/csh
mtaylor:?:769:1375:Mary Tailor:/users/mtaylor:/usr/local/bin/tcsh
dataylor:?:375:518:Dave Tailor:/users/dataylor:/usr/local/lib/msh
taylorjr:?:203:1022:James Tailor:/users/taylorjr:/bin/csh
taylorrj:?:662:1042:Robert Tailor:/users/taylorrj:/bin/csh
taylorm:?:869:1508:Melanie Tailor:/users/taylorm:/bin/csh
taylor:?:1989:1412:Dave Tailor:/users/taylor:/bin/csh
$ grep taylor /etc/passwd | sed -e 's/Taylor/Tailor/g;s/:/ /g'
$ who
strawmye ttyAc Nov 21 19:01
eiyo ttyAd Nov 21 17:40
tzhen ttyAg Nov 21 19:13
kmkernek ttyAh Nov 17 23:22
macedot ttyAj Nov 21 20:41
rpm ttyAk Nov 21 20:40
ypchen ttyAl Nov 21 18:20
kodak ttyAm Nov 21 20:43
$ who | sed 's/tty/On Device /;s/Nov/Logged in November/'
strawmye On Device Ac Logged in November 21 19:01
eiyo On Device Ad Logged in November 21 17:40
tzhen On Device Ag Logged in November 21 19:13
kmkernek On Device Ah Logged in November 17 23:22
macedot On Device Aj Logged in November 21 20:41
rpm On Device Ak Logged in November 21 20:40
ypchen On Device Al Logged in November 21 18:20
kodak On Device Am Logged in November 21 20:43
he sed command also can be used to delete lines in the stream as it passes. The simplest version is to specify only the command:
$ who | sed 'd'
$
$ who | sed '1d'
eiyo ttyAd Nov 21 17:40
tzhen ttyAg Nov 21 19:13
kmkernek ttyAh Nov 17 23:22
macedot ttyAj Nov 21 20:41
rpm ttyAk Nov 21 20:40
ypchen ttyAl Nov 21 18:20
kodak ttyAm Nov 21 20:43
$ who | sed '1,3d'
macedot ttyAj Nov 21 20:41
rpm ttyAk Nov 21 20:40
ypchen ttyAl Nov 21 18:20
kodak ttyAm Nov 21 20:43
$ who | head -15 | sed '/eiyo/,/rpm/d'
root console Nov 9 07:31
rick ttyAa Nov 21 20:58
brunnert ttyAb Nov 21 20:56
ypchen ttyAl Nov 21 18:20
kodak ttyAm Nov 21 20:43
wh ttyAn Nov 21 20:33
klingham ttyAp Nov 21 19:55
linet2 ttyAq Nov 21 20:17
mdps ttyAr Nov 21 20:11
$ who | sed '1,/kmkernek/d'
macedot ttyAj Nov 21 20:41
rpm ttyAk Nov 21 20:40
ypchen ttyAl Nov 21 18:20
kodak ttyAm Nov 21 20:43
$ cat testme
Archives/ OWL/ keylime.pie
InfoWorld/ bin/ src/
Mail/ bitnet.mailing-lists.Z temp/
News/ drop.text.hqx testme
Archives/ OWL/ keylime.pie
InfoWorld/ bin/ src/
Mail/ bitnet.mailing-lists.Z temp/
News/ drop.text.hqx testme
Archives/ OWL/ keylime.pie
InfoWorld/ bin/ src/
Mail/ bitnet.mailing-lists.Z temp/
News/ drop.text.hqx testme
use sed and clean up this output:
$ sed '/^$/d' < testme
Archives/ OWL/ keylime.pie
InfoWorld/ bin/ src/
Mail/ bitnet.mailing-lists.Z temp/
News/ drop.text.hqx testme
Archives/ OWL/ keylime.pie
InfoWorld/ bin/ src/
Mail/ bitnet.mailing-lists.Z temp/
News/ drop.text.hqx testme
Archives/ OWL/ keylime.pie
InfoWorld/ bin/ src/
Mail/ bitnet.mailing-lists.Z temp/
News/ drop.text.hqx testme
$ cat testme | sed '/^$/d;/keylime/d;s/hqx/BinHex/g'
InfoWorld/ bin/ src/
Mail/ bitnet.mailing-lists.Z temp/
News/ drop.text.BinHex testme
InfoWorld/ bin/ src/
Mail/ bitnet.mailing-lists.Z temp/
News/ drop.text.BinHex testme
InfoWorld/ bin/ src/
Mail/ bitnet.mailing-lists.Z temp/
News/ drop.text.BinHex testme
$ cat << EOF > sample
Hey Tai! I’ve been looking for a music CD and none of
the shops around here have a clue about it. I was
wondering if you’re going to have a chance to get into
Tower Records in the next week or so?
EOF
$ sed 's/^/> /' < sample > sample2
$ cat sample2
> Hey Tai! I’ve been looking for a music CD and none of
> the shops around here have a clue about it. I was
> wondering if you’re going to have a chance to get into
> Tower Records in the next week or so?
$ cat sample2 | sed 's/^> //'
Hey Tai! I’ve been looking for a music CD and none of
the shops around here have a clue about it. I was
wondering if you’re going to have a chance to get into
Tower Records in the next week or so?
$ cat << EOF > test.sh
> echo "this is a test!"
> EOF
$ cat > test.sh << EOF
$ cat << EOF >> test.sh
$ cat << ggg > test.sh
> echo "this is a test!"
> ggg
left rooted Patterns that must occur at the beginning of a line.
regular expressions A convenient notation for specifying complex patterns. Notable special characters are ^ to match the beginning of the line and $ to match the end of the line.
wildcards Special characters that are interpreted by the UNIX shell or other programs to have meaning other than the letter itself. For example, * is a shell wildcard and creates a pattern that matches zero or more characters. Prefaced with a particular letter, X—X* —this shell pattern will match all files beginning with X.