-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpygrep
executable file
·210 lines (132 loc) · 4.72 KB
/
pygrep
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
#!/bin/sh
usage="Usage: $(basename $0) [-v|--verbose] [-q|--quiet] [-f|--filenames-only] [-i|--insensitive] EXPR [TARGET_BASE_DIR]: recursive grep in Python source files in order to search for the specified expression in the target sources, either from the TARGET_BASE_DIR directory, if specified, otherwise from the current directory.
Options:
-v or --verbose: be specifically verbose
-q or --quiet: be specifically quiet, just listing matches
-f or --filenames-only: display only filenames, not also the matched patterns, and if there are multiple matches in the same file, its filename will be output only once (implies quiet); useful for scripts
-i or --insensitive: perform case-insensitive searches in the content of files, and also in the searched Python filenames
Example: $(basename $0) -i 'ConfigParser' /tmp"
if [ "$1" = "-h" ] || [ "$1" = "--help" ]; then
echo " ${usage}"
exit
fi
find="$(which find | grep -v ridiculously 2>/dev/null)"
grep="$(which grep | grep -v ridiculously 2>/dev/null)"
#echo "grep = ${grep}"
#echo "find = ${find}"
if [ ! -x "${grep}" ]; then
echo "Error, no executable grep found." 1>&2
exit 5
fi
if [ ! -x "${find}" ]; then
echo "Error, no executable find found." 1>&2
exit 6
fi
# Both are false by default:
verbose=1
quiet=1
insensitive_opt=""
filenames_only=1
# A useless file to ensure grep always has multiple files to scan.
# Done to force grep to display the filename (otherwise it will not)
# No need to create it, however.
#
force_multi_files="$HOME/.$(basename $0).to-delete.tmp"
name_opt="-name"
if [ $# -eq 0 ]; then
echo " Error, too few parameters.
${usage}" 1>&2
exit 1
fi
if [ $# -ge 4 ]; then
echo " Error, too many parameters ($*).
${usage}" 1>&2
exit 2
fi
# Read all known options:
token_eaten=0
while [ ${token_eaten} -eq 0 ]; do
read_parameter="$1"
#echo "read_parameter = ${read_parameter}"
token_eaten=1
if [ "${read_parameter}" = "--verbose" -o "${read_parameter}" = "-v" ]; then
verbose=0
quiet=1
echo "Verbose mode activated."
token_eaten=0
fi
if [ "${read_parameter}" = "--quiet" -o "${read_parameter}" = "-q" ]; then
verbose=1
quiet=0
#echo "Quiet mode activated."
token_eaten=0
fi
if [ "${read_parameter}" = "--filenames-only" -o "${read_parameter}" = "-f" ]; then
verbose=1
quiet=0
filenames_only=0
[ ${quiet} -eq 0 ] || echo "Only filenames will be displayed, not found patterns."
token_eaten=0
fi
if [ "${read_parameter}" = "--insensitive" -o "${read_parameter}" = "-i" ]; then
insensitive_opt="-i"
name_opt="-iname"
[ ${quiet} -eq 0 ] || echo "Case-insensitive mode activated."
token_eaten=0
fi
if [ -n "${read_parameter}" ]; then
shift
fi
done
if [ -z "${read_parameter}" ]; then
echo " Error, too few parameters.
${usage}" 1>&2
exit 3
fi
# full_base_dir is meant to be longer (too long to display before matches) yet
# more precise:
#
target_base_dir="$1"
if [ -z "${target_base_dir}" ]; then
target_base_dir="."
full_base_dir="$(realpath .)"
#[ ${verbose} -eq 0 ] || echo "Proceeding from current directory ('${full_base_dir}')."
else
full_base_dir=$(realpath "${target_base_dir}")
#[ ${verbose} -eq 0 ] || echo "Proceeding from specified directory ('${full_base_dir}')."
shift
fi
if [ ! -d "${target_base_dir}" ]; then
echo " Error, target base directory ('${target_base_dir}') does not exist." 1>&2
exit 10
fi
#echo "target_base_dir = ${target_base_dir}"
searched_expr="${read_parameter}"
#echo "searched_expr = ${searched_expr}"
# Then check no parameter remains:
if [ $# -ge 1 ]; then
echo " Error, too many parameters (remaining: '$*').
${usage}" 1>&2
exit 4
fi
base_grep_opt="--color"
# NEVER surround these single quotes by double ones:
filter_py='*.py'
# Unable to properly define a correctly-protected variable:
#filter_expr="${name_opt} ${filter_py}"
if [ ${verbose} -eq 0 ]; then
#echo "Will search in following files from '${target_base_dir}' based on: ${find} . ${filter_expr}:"
echo "Will search in following files from '${target_base_dir}' based on: ${find} . ${name_opt} ${filter_py}:"
${find} "${target_base_dir}" ${name_opt} "${filter_py}"
fi
[ ${quiet} -eq 0 ] || echo "
Recursive grep for expression <${searched_expr}> in all Python files from '${full_base_dir}' (i.e. '${target_base_dir}'):
"
if [ ${filenames_only} -eq 1 ]; then
# Most usual case:
${find} "${target_base_dir}" ${name_opt} "${filter_py}" -exec ${grep} ${base_grep_opt} ${insensitive_opt} "${searched_expr}" '{}' ${force_multi_files} ';' 2>/dev/null
else
${find} "${target_base_dir}" ${name_opt} "${filter_py}" -exec ${grep} ${base_grep_opt} ${insensitive_opt} "${searched_expr}" '{}' ${force_multi_files} ';' 2>/dev/null | sed 's|:.*$||1' | uniq
fi
[ ${quiet} -eq 0 ] || echo "
End of search."