-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathforeachfile
More file actions
executable file
·109 lines (84 loc) · 2.19 KB
/
foreachfile
File metadata and controls
executable file
·109 lines (84 loc) · 2.19 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
#!/bin/bash
#
# foreachfile
#
# filename placeholder token to be used from the command line and for
# substitution in the individual commands
#
token="%"
usagestr=$(
cat <<EOF
foreachfile filespec body
filespec - file specification, can have wildcards
body - body of the loop
Both filespec and body must be enclosed in double quotes.
In the body of the loop, the current file is denoted by
this token: '$token'
Use \\ to escape \\ , %, $, etc.
Example:
foreachfile "*.patch" "echo $token; grep -m1 'Subject' $token"
\0
EOF
)
usage() {
echo -e "$usagestr"
exit
}
# parse_cmd
#
# If the command contains the token, then replace it with the current filename
# and execute the command.
#
# $1 - current filename
# $2 - command
#
parse_cmd() {
local file="$1" # get the name of the current file
shift # shift past the filename
local cmd="$@" # remainder of command line is command string
local ary=($cmd) # create an array from the command string
local index=0 # index for the array
for index in "${!ary[@]}"; do
[[ ${ary[$index]} == "$token" ]] && ary[$index]="$file"
done
echo "${ary[@]}" >> /tmp/cmd
}
[ $# -gt 0 ] || usage
# shopt -s extglob
declare filespec="$1" # file specification including wildcards
declare files=$(ls -1 $filespec) # list of files
echo -e \
" List of Files\n"\
"============="
echo "$files"
shift # shift past the file specification
declare body="$@" # remainder of command line is loop body
declare cmdary # array of commands to be executed in loop
# Create a dummy script file to execute the commands
#
touch /tmp/cmd
chmod +x /tmp/cmd
# Tokenize the loop body into an array using ';' as the IFS separator.
#
IFS=";" read -ra cmdary <<<"$body"
echo -e \
"\n List of Commands\n"\
"================"
for key in "${!cmdary[@]}"; do echo $key ${cmdary[$key]}; done
# For each for the files in the list, execute the body of commands
#
for f in $files; do
> /tmp/cmd
# Substitute the token with the file name in each command that has
# a token and write the command line out to the /tmp/cmd file.
#
for key in "${!cmdary[@]}"; do
parse_cmd $f "${cmdary[$key]}"
done
# Execute the commands
#
/tmp/cmd
done
# Delete the dummy script file
#
rm -f /tmp/cmd