Useful UNIX Shell Commands
=========================================
It seems I keep bumping into situations which repeat. I list below some UNIX shell commands I've used on many occasions.
grep
----
Case insensitive search:
grep -i
Demo: grep -i bizVigyan danny.txt
List files which contain pattern:
grep -l
Demo: grep -l bizVigyan *.txt
Return lines which do not match:
grep -v
Demo: grep -v bizVigyan billy.txt
find
----
Find may be used to find a file. Also I use it to generate lists of files which
fit some kind of pattern. The lists can than be fed to other shell commands.
Self Explanatory Demos:
---------------------------------
bizVigyan04-oracle-% /bin/find . -name initbizVigyandev.ora -print
./dbs/initbizVigyandev.ora
bizVigyan04-oracle-%
bizVigyan04-oracle-% /bin/find . -name 'init*.ora' -print
./dbs/initbizVigyandev.ora
./dbs/initbizVigyantest.ora
./dbs/initbizVigyanrc.ora
./hs/admin/inithsodbc.ora
bizVigyan04-oracle-%
bizVigyan04-oracle-% /bin/find . -type l -print
./bin/runInstaller
./lib/libagtsh.so
./lib/libobk.so
./lib/libclntsh.so
./precomp/public/SQLCA.H
bizVigyan04-oracle-%
bizVigyan04-oracle-% /bin/find . -type l -exec /bin/ls -l {} \;
lrwxrwxrwx 1 oracle dba 56 Jul 18 2000 ./bin/runInstaller ->
disk/u01/app/oracle/product/oui/install/runInstaller.sh
lrwxrwxrwx 1 oracle dba 15 Jul 18 2000 ./lib/libagtsh.so -> libagtsh.so.1.0
lrwxrwxrwx 1 oracle dba 13 Jul 18 2000 ./lib/libobk.so -> libdsbtsh8.so
lrwxrwxrwx 1 oracle dba 16 Jul 18 2000 ./lib/libclntsh.so -> libclntsh.so.8.0
lrwxrwxrwx 1 oracle dba 7 Jul 18 2000 ./precomp/public/SQLCA.H -> sqlca.h
bizVigyan04-oracle-%
I think of the 'xargs' keyword as a magic wand which moves a group of tokens
from the left to the right and squish them onto one line.
Here is ASCII art which describes my mental picture:
aabbcc
xxyyzz
112233 -> xargs -> aabbcc xxyyzz 112233 uu bye
uu
bye
The 'xargs' keyword works well with the 'find' command because the 'find' command
lists file names in a single column.
This demo uses 'xargs' keyword to do the same thing as the
/bin/find . -type l -exec /bin/ls -l {} \;
demo.
bizVigyan04-oracle-% /bin/find . -type l -print | xargs /bin/ls -l
lrwxrwxrwx 1 oracle dba 56 Jul 18 2000 ./bin/runInstaller ->
disk/u01/app/oracle/product/oui/install/runInstaller.sh lrwxrwxrwx 1 oracle dba 15 Jul 18
2000 ./lib/libagtsh.so -> libagtsh.so.1.0
lrwxrwxrwx 1 oracle dba 16 Jul 18 2000 ./lib/libclntsh.so -> libclntsh.so.8.0
lrwxrwxrwx 1 oracle dba 7 Jul 18 2000 ./precomp/public/SQLCA.H -> sqlca.h
bizVigyan04-oracle-%
Notice how /bin/ls does the opposite of xargs; it takes a list of
files on a single command line and transforms the list into a column of file names.
Now we demonstrate 'find' sending a bunch of file names to grep:
/bin/find . -type f -print | xargs | grep -l bizVigyan
The above command finds all files (in a tree!) which contain the string 'bizVigyan'.
The 'find' command is also useful for finding files based on date.
The command below finds all files younger than 7 days:
/bin/find . -type f -mtime -7 -print
The command below finds all files older than 7 days:
/bin/find . -type f -mtime +7 -print
Since 'find' can find files based on date, it works well with cpio:
/bin/find . -type f -mtime -7 -print | /bin/cpio -o > /tmp/newerFiles.cpio
The above shell command could be considered a low-tech incremental backup.
To check the contents of the backup, we'd do something like this:
cat /tmp/newerFiles.cpio | /bin/cpio -it
perl
----
Perl is a great language. Often, I use it to edit collections of files.
If I want to edit just one file I'd do something like this:
perl -e 's/Smith/Bikle/gi' -p -i.bak aFileIwantChanged.txt
If I want to edit all the files in a tree of directories, I'd use find, grep, and xargs to locate the names and then
feed the list to a perl command similar to the one above:
/bin/find . -type f -print | xargs /bin/grep -l Smith | xargs perl -e 's/Smith/Bikle/gi' -p -i.bak
Note that if perl changes any files it will back up the original copies to files with a '.bak' suffix. If we are confident the perl edits are okay, we may remove the .bak files with a command like
this:
/bin/find . -type f -name '*.bak' -print | xargs /bin/grep -l Smith | xargs /bin/rm
Yes, perl is a useful tool; I may put together a directory full of useful perl scripts when I get some free time.
Miscellaneous
--------------
If I want to edit a file and put the results in another file, I'd use sed rather than perl:
cat initSMITH.ora|/bin/sed '1,$s,SMITH,bizVigyan,g'>initbizVigyan.ora
Here is a command I use to look at some hardware configuration information on a Solaris host:
/usr/platform/sun4u/sbin/prtdiag
Here is a demo command I use to kill a set of processes which fit a grepable pattern:
/bin/ps -ef |/bin/grep oraclebizVigyan|/bin/awk '{print $2}' | xargs kill
Sometimes /var/adm/messages can contain interesting information:
/bin/tail /var/adm/messages
Netstat contains connection information between your host and others.
For example it can help answer, "Who is connected on port 1521?":
/bin/netstat -a|/bin/grep 1521
Here is another awk demo which I've not actually used yet but does
demonstrate 2 good ideas. The first idea is that I can use the '-F' option to specify a field separator in the file I'm passing to awk.
For example, the /etc/passwd file contains fields separated by ':'.
The second idea is that awk has some SQL-like functionality. For example, if I want to select (perhaps display would be a better verb)
the value of the first column for all lines in /etc/passwd where the third column value is "0", I'd type this:
cat /etc/passwd | /bin/awk -F: '$3 == "0" {print $1}'
A rough SQL equivalent would be this:
SELECT column1 FROM /etc/passwd WHERE column3 = '0';
Here is another awk demo which acts like the SQL function named SUM().
cat /etc/group | /bin/awk -F: '{sum+=$3}END{print sum}'
In SQL terms it would be like this:
SELECT SUM(column3) FROM /etc/group;
A Recap
-------
/bin/find . -name 'init*.ora' -print
/bin/find . -type l -print
/bin/find . -type l -exec /bin/ls -l {} \;
/bin/find . -type l -print | xargs /bin/ls -l
/bin/find . -type f -print | xargs grep -l bizVigyan
/bin/find . -type f -mtime -7 -print
/bin/find . -type f -mtime +7 -print
/bin/find . -type f -mtime -7 -print | /bin/cpio -o > /tmp/newerFiles.cpio
cat /tmp/newerFiles.cpio | /bin/cpio -it
perl -e 's/Smith/Bikle/gi' -p -i.bak aFileIwantChanged.txt
/bin/find . -type f -print | xargs /bin/grep -l Smith | xargs perl -e 's/Smith/Bikle/gi' -p -i.bak
/bin/find . -type f -name '*.bak' -print | /bin/grep -l Smith | xargs /bin/rm
cat initSMITH.ora|/bin/sed '1,$s,SMITH,bizVigyan,g'>initbizVigyan.ora
/usr/platform/sun4u/sbin/prtdiag
/bin/ps -ef |/bin/grep oraclebizVigyan|/bin/awk '{print $2}' | xargs kill
/bin/tail /var/adm/messages
/bin/netstat -a|/bin/grep 1521
cat /etc/passwd | /bin/awk -F: '$3 == "0" {print $1}'
cat /etc/group | /bin/awk -F: '{sum+=$3}END{print sum}'
Friday, February 12, 2010
Subscribe to:
Post Comments (Atom)

Your use of xargs can lead to nasty surprises because of the separator
ReplyDeleteproblem http://en.wikipedia.org/wiki/Xargs#The_separator_problem
GNU Parallel http://www.gnu.org/software/parallel/ does not have that
problem.
Watch the intro video for GNU Parallel:
http://www.youtube.com/watch?v=OpaiGYxkSuQ