foreach: ajouter une syntaxe alternative pour lister directement les éléments
This commit is contained in:
parent
24a8839fec
commit
6a4e6a7146
|
@ -5,11 +5,16 @@ foreach: lancer une commande pour un ensemble d'arguments
|
|||
|
||||
USAGE
|
||||
foreach [options] [VAR=]expr cmd...
|
||||
foreach [options] [VAR=]items... -- cmd...
|
||||
|
||||
La commande est lancée avec la variable 'VAR', qui vaut par défaut 'item',
|
||||
définie à la valeur courante de l'énumération. De plus, la variable 'index'
|
||||
reçoit une valeur incrémentale commençant à 0.
|
||||
|
||||
La deuxième syntaxe appelée syntaxe alternative permet de spécifier un ensemble
|
||||
d'éléments directement, mais nécessite l'utilisation du séparateur '--' pour
|
||||
identifier où s'arrête la liste des éléments.
|
||||
|
||||
En plus de VAR, les variables file, dir, name, basename, ext et dotext sont
|
||||
définies. Elle valent respectivement le chemin absolu du fichier, le répertoire
|
||||
absolu du fichier, le nom du fichier, le nom de base sans extension, l'extension
|
||||
|
@ -17,22 +22,32 @@ sans le point et l'extension avec le point, e.g pour item=dir/file.ext on a
|
|||
file=/path/to/dir/file.ext, dir=/path/to/dir, name=file.ext, basename=file,
|
||||
ext=ext, dotext=.ext
|
||||
|
||||
Exemple:
|
||||
Les 3 exemples suivants sont équivalents:
|
||||
foreach '*.c' cp %item dest/dir
|
||||
Equivalent à:
|
||||
foreach item='*.c' cp %item dest/dir
|
||||
foreach *.c -- cp %item dest/dir
|
||||
|
||||
OPTIONS
|
||||
-b, --basedir BASEDIR
|
||||
Chercher les expressions -d, -f, -a à partir de BASEDIR au lieu du
|
||||
répertoire courant.
|
||||
-d, --dir
|
||||
Faire la correspondance de l'expression sur les répertoires uniquement
|
||||
-f, --file
|
||||
Faire la correspondance de l'expression sur les fichier uniquement
|
||||
-a, --all
|
||||
Faire la correspondance de l'expression sur les répertoires et les
|
||||
fichiers
|
||||
-s, --string
|
||||
Ces options permettent de spécifier le type d'expression et la façon de
|
||||
les traiter. Avec -d, faire la correspondance de l'expression sur les
|
||||
répertoires uniquement. Avec -f, faire la correspondance sur les fichier
|
||||
uniquement. Avec -a, faire la correspondance sur les répertoires et les
|
||||
fichiers. Avec -s, évaluer l'expression avec la fonction 'eval' du
|
||||
shell.
|
||||
Si la syntaxe alternative est utilisée, le premier élément est évalué
|
||||
conformément à ces options *si et seulement s'il* est précédé d'une
|
||||
chaine 'VAR='. Les autres éléments sont pris tels-quels. e.g:
|
||||
cette commande affiche uniquement la chaine '*.c':
|
||||
foreach '*.c' --
|
||||
alors que celle-ci liste les fichiers qui ont l'extension '.c':
|
||||
foreach 'item=*.c' --
|
||||
-p, --parent
|
||||
Pour chaque fichier/répertoire, se placer dans le répertoire parent
|
||||
avant de lancer la commande. item est aussi modifié pour ne plus
|
||||
|
@ -47,14 +62,12 @@ OPTIONS
|
|||
la cible, soit '.' pour le répertoire courant, soit le nom du fichier
|
||||
dans le répertoire courant.
|
||||
Si cette option est mentionnée seule, elle implique --dir
|
||||
-s, --string
|
||||
Evaluer l'expression avec la fonction 'eval' du shell.
|
||||
-x, --expand
|
||||
-n, --no-expand
|
||||
Reconnaitre et traiter (resp. ne pas reconnaitre) la syntaxe %var dans
|
||||
les arguments. C'est le cas par défaut, ce qui permet de simplifier
|
||||
l'écriture d'une ligne de commande. Pour écrire le caractère '%', il
|
||||
suffit de le double e.g %%item
|
||||
suffit de le doubler e.g %%item
|
||||
Si l'expansion est désactivée, il faut protéger le caractère $ pour
|
||||
qu'il soit traité, e.g, avec les examples ci-dessus:
|
||||
foreach -n '*.c' 'cp "$item" dest/dir'
|
||||
|
|
125
foreach
125
foreach
|
@ -8,11 +8,16 @@ function display_help() {
|
|||
|
||||
USAGE
|
||||
$scriptname [options] [VAR=]expr cmd...
|
||||
$scriptname [options] [VAR=]items... -- cmd...
|
||||
|
||||
La commande est lancée avec la variable 'VAR', qui vaut par défaut 'item',
|
||||
définie à la valeur courante de l'énumération. De plus, la variable 'index'
|
||||
reçoit une valeur incrémentale commençant à 0.
|
||||
|
||||
La deuxième syntaxe appelée syntaxe alternative permet de spécifier un ensemble
|
||||
d'éléments directement, mais nécessite l'utilisation du séparateur '--' pour
|
||||
identifier où s'arrête la liste des éléments.
|
||||
|
||||
En plus de VAR, les variables file, dir, name, basename, ext et dotext sont
|
||||
définies. Elle valent respectivement le chemin absolu du fichier, le répertoire
|
||||
absolu du fichier, le nom du fichier, le nom de base sans extension, l'extension
|
||||
|
@ -20,22 +25,32 @@ sans le point et l'extension avec le point, e.g pour item=dir/file.ext on a
|
|||
file=/path/to/dir/file.ext, dir=/path/to/dir, name=file.ext, basename=file,
|
||||
ext=ext, dotext=.ext
|
||||
|
||||
Exemple:
|
||||
Les 3 exemples suivants sont équivalents:
|
||||
$scriptname '*.c' cp %item dest/dir
|
||||
Equivalent à:
|
||||
$scriptname item='*.c' cp %item dest/dir
|
||||
$scriptname *.c -- cp %item dest/dir
|
||||
|
||||
OPTIONS
|
||||
-b, --basedir BASEDIR
|
||||
Chercher les expressions -d, -f, -a à partir de BASEDIR au lieu du
|
||||
répertoire courant.
|
||||
-d, --dir
|
||||
Faire la correspondance de l'expression sur les répertoires uniquement
|
||||
-f, --file
|
||||
Faire la correspondance de l'expression sur les fichier uniquement
|
||||
-a, --all
|
||||
Faire la correspondance de l'expression sur les répertoires et les
|
||||
fichiers
|
||||
-s, --string
|
||||
Ces options permettent de spécifier le type d'expression et la façon de
|
||||
les traiter. Avec -d, faire la correspondance de l'expression sur les
|
||||
répertoires uniquement. Avec -f, faire la correspondance sur les fichier
|
||||
uniquement. Avec -a, faire la correspondance sur les répertoires et les
|
||||
fichiers. Avec -s, évaluer l'expression avec la fonction 'eval' du
|
||||
shell.
|
||||
Si la syntaxe alternative est utilisée, le premier élément est évalué
|
||||
conformément à ces options *si et seulement s'il* est précédé d'une
|
||||
chaine 'VAR='. Les autres éléments sont pris tels-quels. e.g:
|
||||
cette commande affiche uniquement la chaine '*.c':
|
||||
$scriptname '*.c' --
|
||||
alors que celle-ci liste les fichiers qui ont l'extension '.c':
|
||||
$scriptname 'item=*.c' --
|
||||
-p, --parent
|
||||
Pour chaque fichier/répertoire, se placer dans le répertoire parent
|
||||
avant de lancer la commande. item est aussi modifié pour ne plus
|
||||
|
@ -50,14 +65,12 @@ OPTIONS
|
|||
la cible, soit '.' pour le répertoire courant, soit le nom du fichier
|
||||
dans le répertoire courant.
|
||||
Si cette option est mentionnée seule, elle implique --dir
|
||||
-s, --string
|
||||
Evaluer l'expression avec la fonction 'eval' du shell.
|
||||
-x, --expand
|
||||
-n, --no-expand
|
||||
Reconnaitre et traiter (resp. ne pas reconnaitre) la syntaxe %var dans
|
||||
les arguments. C'est le cas par défaut, ce qui permet de simplifier
|
||||
l'écriture d'une ligne de commande. Pour écrire le caractère '%', il
|
||||
suffit de le double e.g %%item
|
||||
suffit de le doubler e.g %%item
|
||||
Si l'expansion est désactivée, il faut protéger le caractère \$ pour
|
||||
qu'il soit traité, e.g, avec les examples ci-dessus:
|
||||
$scriptname -n '*.c' 'cp \"\$item\" dest/dir'
|
||||
|
@ -97,10 +110,58 @@ if [ "$match" == auto ]; then
|
|||
fi
|
||||
fi
|
||||
|
||||
alt_syntax=
|
||||
for sep in "$@"; do
|
||||
if [ "$sep" == -- ]; then
|
||||
alt_syntax=1
|
||||
break
|
||||
fi
|
||||
done
|
||||
suppl_items=()
|
||||
varexpr="$1"; shift
|
||||
if [ -n "$alt_syntax" ]; then
|
||||
while [ $# -gt 0 ]; do
|
||||
[ "$1" == -- ] && break
|
||||
array_add suppl_items "$1"
|
||||
shift
|
||||
done
|
||||
[ "$1" == -- ] && shift
|
||||
fi
|
||||
splitfsep2 "$varexpr" = varname expr
|
||||
[ -n "$varname" ] || varname=item
|
||||
[ -n "$expr" ] || expr="*"
|
||||
if [ -n "$alt_syntax" ]; then
|
||||
if [ -n "$varname" ]; then
|
||||
[ -n "$expr" ] || expr="*"
|
||||
elif [[ "$varexpr" == *=* ]]; then
|
||||
[ -n "$varname" ] || varname=item
|
||||
[ -n "$expr" ] || expr="*"
|
||||
else
|
||||
items=("$varexpr")
|
||||
varname=item
|
||||
expr=
|
||||
fi
|
||||
else
|
||||
[ -n "$varname" ] || varname=item
|
||||
[ -n "$expr" ] || expr="*"
|
||||
fi
|
||||
if [ -n "$expr" ]; then
|
||||
if [ -n "$basedir" ]; then
|
||||
case "$match" in
|
||||
all) array_lsall items "$basedir" "$expr";;
|
||||
dir) array_lsdirs items "$basedir" "$expr";;
|
||||
file) array_lsfiles items "$basedir" "$expr";;
|
||||
string) eval "items=($expr)";;
|
||||
esac
|
||||
else
|
||||
basedir=.
|
||||
case "$match" in
|
||||
all) array_from_lines items "$(list_all "$basedir" "$expr")";;
|
||||
dir) array_from_lines items "$(list_dirs "$basedir" "$expr")";;
|
||||
file) array_from_lines items "$(list_files "$basedir" "$expr")";;
|
||||
string) eval "items=($expr)";;
|
||||
esac
|
||||
fi
|
||||
fi
|
||||
array_extend items suppl_items
|
||||
|
||||
cmd=("$@")
|
||||
if [ ${#cmd[*]} -eq 0 ]; then
|
||||
|
@ -111,33 +172,20 @@ if [ ${#cmd[*]} -eq 0 ]; then
|
|||
fi
|
||||
fi
|
||||
|
||||
if [ -n "$basedir" ]; then
|
||||
case "$match" in
|
||||
all) array_lsall items "$basedir" "$expr";;
|
||||
dir) array_lsdirs items "$basedir" "$expr";;
|
||||
file) array_lsfiles items "$basedir" "$expr";;
|
||||
string) eval "items=($expr)";;
|
||||
esac
|
||||
else
|
||||
basedir=.
|
||||
case "$match" in
|
||||
all) array_from_lines items "$(list_all "$basedir" "$expr")";;
|
||||
dir) array_from_lines items "$(list_dirs "$basedir" "$expr")";;
|
||||
file) array_from_lines items "$(list_files "$basedir" "$expr")";;
|
||||
string) eval "items=($expr)";;
|
||||
esac
|
||||
fi
|
||||
|
||||
[ -n "$title" ] && einfo "${#items[@]} correspondance(s) trouvée(s)"
|
||||
let index=0
|
||||
for item in "${items[@]}"; do
|
||||
[ -n "$title" ] && etitle "$item"
|
||||
i="$item"
|
||||
setx file=abspath "$item"
|
||||
setx dir=dirname -- "$file"
|
||||
setx name=basename -- "$file"
|
||||
splitname "$name" basename ext
|
||||
[[ "$name" == *.* ]] && dotext=".$ext" || dotext=
|
||||
export file dir name basename ext dotext
|
||||
# ne pas changer les noms des variables sans modifier le script awk
|
||||
# ci-dessous
|
||||
__VARS=(i file dir name basename ext dotext)
|
||||
export "${__VARS[@]}"
|
||||
(
|
||||
if [ -n "$changedir" ]; then
|
||||
if [ -f "$item" ]; then
|
||||
|
@ -154,13 +202,17 @@ for item in "${items[@]}"; do
|
|||
cd "$item"
|
||||
item=.
|
||||
fi
|
||||
i="$item"
|
||||
|
||||
__VALUES=()
|
||||
for __VALUE in "${__VARS[@]}"; do
|
||||
array_add __VALUES "$__VALUE=${!__VALUE}"
|
||||
done
|
||||
|
||||
if [ -n "$expand" ]; then
|
||||
array_from_lines cmd "$(awkrun -f \
|
||||
file="$file" dir="$dir" name="$name" basename="$basename" ext="$ext" dotext="$dotext" \
|
||||
xitem="$index" item="$item" varname="$varname" cmd[@] \
|
||||
'
|
||||
array_from_lines cmd "$(awkrun -f "${__VALUES[@]}" xitem="$index" item="$item" varname="$varname" cmd[@] '
|
||||
function replace_vars(src, re, vs, dest) {
|
||||
re = "(%(file|dir|name|basename|ext|dotext|index|" varname "))"
|
||||
re = "(%(" varname "|i|file|dir|name|basename|ext|dotext|index))"
|
||||
while (src != "") {
|
||||
if (match(src, "%%") != 0) {
|
||||
dest = dest substr(src, 1, RSTART)
|
||||
|
@ -175,14 +227,15 @@ function replace_vars(src, re, vs, dest) {
|
|||
break
|
||||
}
|
||||
var = vs[2]
|
||||
if (var == "file") dest = dest file
|
||||
if (var == varname) dest = dest item
|
||||
else if (var == "i") dest = dest item
|
||||
else if (var == "file") dest = dest file
|
||||
else if (var == "dir") dest = dest dir
|
||||
else if (var == "name") dest = dest name
|
||||
else if (var == "basename") dest = dest basename
|
||||
else if (var == "ext") dest = dest ext
|
||||
else if (var == "dotext") dest = dest dotext
|
||||
else if (var == "index") dest = dest xitem
|
||||
else if (var == varname) dest = dest item
|
||||
}
|
||||
if (src != "") dest = dest src
|
||||
return dest
|
||||
|
|
Loading…
Reference in New Issue