Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
6725 | siemargl | 1 | #!/bin/sh |
2 | # |
||
3 | # zipgrep: Use unzip and egrep to search the specified members of a |
||
4 | # Zip archive for a string or pattern. Search all members if no members |
||
5 | # are specified explicitly. The script attempts to handle egrep's "-h" |
||
6 | # and "-l" options internally. |
||
7 | # |
||
8 | # This script assumes that the desired "unzip" and "egrep" (and "sed") |
||
9 | # programs are on the user's PATH. |
||
10 | # |
||
11 | |||
12 | pat="" |
||
13 | opt="" |
||
14 | while test $# -ne 0; do |
||
15 | case "$1" in |
||
16 | -e | -f) opt="$opt $1"; shift; pat="$1";; |
||
17 | -*) opt="$opt $1";; |
||
18 | *) if test -z "$pat"; then |
||
19 | pat="$1" |
||
20 | else |
||
21 | break; |
||
22 | fi;; |
||
23 | esac |
||
24 | shift |
||
25 | done |
||
26 | |||
27 | if test $# = 0; then |
||
28 | echo usage: `basename "$0"` "[egrep_options] pattern zipfile [members...]" |
||
29 | echo Uses unzip and egrep to search the zip members for a string or pattern. |
||
30 | exit 1 |
||
31 | fi |
||
32 | zipfile="$1"; shift |
||
33 | |||
34 | list=0 |
||
35 | silent=0 |
||
36 | opt=`echo "$opt" | sed -e 's/ //g' -e 's/-//g'` |
||
37 | case "$opt" in |
||
38 | *l*) list=1; opt=`echo $opt | sed s/l//` |
||
39 | esac |
||
40 | case "$opt" in |
||
41 | *h*) silent=1 |
||
42 | esac |
||
43 | if test -n "$opt"; then |
||
44 | opt="-$opt" |
||
45 | fi |
||
46 | |||
47 | status_grep_global=1 |
||
48 | IFS=' |
||
49 | ' |
||
50 | |||
51 | # Escape shell-special characters in "pat". |
||
52 | pat=` echo "$pat" | \ |
||
53 | sed -e 's/\\\\/\\\\\\\\/g' -e 's/|/\\\|/g' -e 's/&/\\\&/g' ` |
||
54 | |||
55 | # Use "unzip -Z1" to get a listing of the specified members from the |
||
56 | # specified archive. Escape any backslashes in a file name. |
||
57 | for i in `unzip -Z1 "$zipfile" ${1+"$@"} | sed -e 's/\\\\/\\\\\\\\/g' `; do |
||
58 | if test $list -eq 1; then |
||
59 | # "-l": Show only the archive member name, not the matching line(s). |
||
60 | unzip -p-L "$zipfile" "$i" | \ |
||
61 | egrep $opt "$pat" > /dev/null && echo "$i" |
||
62 | status_grep=$? |
||
63 | elif test $silent -eq 1; then |
||
64 | # "-h": Show only the matching line(s), not the archive member name. |
||
65 | # ("-s" in "opt" will silence "egrep", stopping all output.) |
||
66 | unzip -p-L "$zipfile" "$i" | \ |
||
67 | egrep $opt "$pat" |
||
68 | status_grep=$? |
||
69 | else |
||
70 | # Escape (or re-escape) shell-special characters in the archive |
||
71 | # member name, "i". |
||
72 | i=` echo "$i" | \ |
||
73 | sed -e 's/\\\\/\\\\\\\\/g' -e 's/|/\\\|/g' -e 's/&/\\\&/g' ` |
||
74 | |||
75 | # Globally, send fd 4 to stdout. In the pipeline, send normal |
||
76 | # stdout to fd 4, and send grep status to fd 3. Collect fd 3 |
||
77 | # with ``. |
||
78 | exec 4>&1 |
||
79 | status_grep=` ( \ |
||
80 | ( unzip -p-L "$zipfile" "$i" | \ |
||
81 | egrep $opt "$pat" 1>&4 ; echo $? >&3 ) 4>&1 | \ |
||
82 | sed "s|^|${i}:|" 1>&4 \ |
||
83 | ) 3>&1 ` |
||
84 | fi |
||
85 | |||
86 | # Save the primary command status. (May be the grep status.) |
||
87 | sts=$? |
||
88 | # If this grep status was zero, set the global grep status to zero. |
||
89 | test "$status_grep" -eq 0 && status_grep_global=0 |
||
90 | # If this grep status was not zero or one, exit now. |
||
91 | test "$status_grep" -gt 1 && exit "$status_grep" |
||
92 | |||
93 | done |
||
94 | |||
95 | # If "sts" is good (0), then exit with the global grep status. |
||
96 | # Else, when "sts" is bad, exit with the worst status we can find. |
||
97 | if test $sts -eq 0 ; then |
||
98 | exit $status_grep_global |
||
99 | else |
||
100 | if test "$status_grep" -gt 1 ; then |
||
101 | exit "$status_grep" |
||
102 | else |
||
103 | exit $sts |
||
104 | fi |
||
105 | fi |