Repository navigation
Expand file tree
/
Copy pathmapdir
More file actions
executable file
·181 lines (146 loc) · 3.86 KB
/
Copy pathmapdir
File metadata and controls
executable file
·181 lines (146 loc) · 3.86 KB
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
#! /usr/bin/env bash
set -eu
me=$(basename $0)
function usage {
[ "${*-}" ] && echo "$me: $*" 1>&2
cat 1>&2 <<EOF
Usage: $me [-n] [-h] directory ext prog [args]
'prog' is called, with args (see below), on each file in 'directory'
which has file type 'ext'. 'args' must contain at least one argument,
from the following two-character sequences. They are converted as
follows, where 'file' refers to the matching file:
%p => full pathname of file
%d => dirname of file
%b => basename of file
%n => basename of file sans type
Options:
-n :: do not execute, just print the commands
-h :: ignore hidden files (ones that start with a dot)
Examples:
\$ $me \$HOME md \$HOME/bin/convert-md-to-html -o %n.html %b
\$ $me \$HOME md /bin/echo %p
EOF
exit 1
}
function errordie {
[ "${*-}" ] && echo "$me: $*" 1>&2
exit 1
}
ignorehidden=
noexecute=
while [ $# -gt 0 ]; do
case $1 in
-h) ignorehidden=$1 ;;
-n) noexecute=$1 ;;
-*) usage unknown command line argument: $1 ;;
*) break ;;
esac
shift
done
[ $# -ge 4 ] || usage too few arguments: $*
directory=$1; shift
ext=$1 ; shift
prog=$1 ; shift
# There is at least one argument
origin_args="$@"
[ -d "$directory" ] || usage directory $directory does not exist
[ -L "$prog" ] && prog="$(readlink "$prog")"
if [ -x "$prog" ]; then
: # given pull path to prog
elif type -p "$prog" > /dev/null; then
: # exists as a command
else
usage program $prog does not exist
fi
function quote_for_sed {
sed -e 's,&,\\\&,g'
}
# Input: pathname [args ...]
# Output: [args ...] substituted with %x patterns.
function substitute {
local p="$1"
shift
local d="$(dirname "$p")"
local b="$(basename "$p")"
local n="${b%.*}"
for arg in "$@"; do
echo $arg | substitute_sed
echo -n " "
done
}
function substitute_sed {
local pp="$(echo $p | quote_for_sed)"
local dd="$(echo $d | quote_for_sed)"
local bb="$(echo $b | quote_for_sed)"
local nn="$(echo $n | quote_for_sed)"
local res="$(sed -e "s|%p|$pp|g" -e "s|%d|$dd|g" -e "s|%b|$bb|g" -e "s|%n|$nn|g")"
# If the expansion has a space in it, we need to quote it
if [[ "$res" =~ \ ]]; then
echo -n \"$res\"
else
echo -n $res
fi
}
# Check that arguments have at least one %x sequence.
[ "$*" = "$(substitute /a/b/c.txt $*)" ] &&
usage did not find any % escapes
n=0
tempnames=/tmp/mapdirN$$
script=/tmp/mapdirS$$
rm -f $tempnames $script
# remove $script on SIGINT, but leave it around for debugging should
# the program dies, for some reason.
trap _my_trap_EXIT_handler EXIT
trap _my_trap_INT_handler INT
function _my_trap_EXIT_handler {
echo "# EXIT: removing $tempnames" 1>&2
/bin/rm -f $tempnames
if [ -f "$script" ]; then
echo "ERROR executing this script: $script"
fi
}
function _my_trap_INT_handler {
echo "# SIGINT: removing $script" 1>&2
/bin/rm -f $script
}
if [ "$ignorehidden" ]; then
find $directory -iname "[^.]*${ext}" -print > $tempnames
else
find $directory -name "*${ext}" -print > $tempnames
fi
wc=($(wc -l $tempnames))
max=${wc[0]}
## For some reason, executing the commands in a `while' loop
## reading from $tempnames exits after the first one. So, convert
## it to a script that prints progress.
cat > $script <<EOF
#! /usr/bin/env bash
set -eu
EOF
chmod 755 $script
{
IFS=
while read line; do
n=$(( n + 1 ))
echo echo =============== $prog: doing $n of $max >> $script
echo date >> $script
echo $prog $(substitute "$line" $@) >> $script
done <<< "$(cat $tempnames)"
rm -f $tempnames
if [ "$noexecute" ]; then
cat <<EOF
Would have executed script $script
Contents:
$(cat $script)
EOF
else
$script
fi
rm -f $script
if [ "$noexecute" ]; then
trap "" EXIT
else
trap "echo $me: SUCCESS" EXIT
fi
exit 0
}