205 lines
		
	
	
		
			6.6 KiB
		
	
	
	
		
			Bash
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			205 lines
		
	
	
		
			6.6 KiB
		
	
	
	
		
			Bash
		
	
	
		
			Executable File
		
	
	
	
	
| #!/bin/bash
 | |
| # -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8
 | |
| source "$(dirname "$0")/lib/ulib/ulib" || exit 1
 | |
| urequire DEFAULTS
 | |
| 
 | |
| function display_help() {
 | |
|     uecho "$scriptname: lancer une commande pour un ensemble d'arguments
 | |
| 
 | |
| USAGE
 | |
|     $scriptname [options] [VAR=]expr 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.
 | |
| 
 | |
| 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
 | |
| 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:
 | |
|     $scriptname '*.c' cp %item dest/dir
 | |
| Equivalent à:
 | |
|     $scriptname item='*.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
 | |
|     -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
 | |
|         contenir que le nom de la cible (qui est désormais dans le répertoire
 | |
|         courant)
 | |
|         Cette option a la priorité sur --go
 | |
|     -g, --go
 | |
|         Si la cible est un répertoire, en faire le répertoire courant avant de
 | |
|         lancer la commande. Si la cible est un fichier, faire comme --parent et
 | |
|         se placer dans le répertoire du fichier avant de lancer la commande.
 | |
|         Dans les deux cas, item est modifié pour ne plus contenir que le nom de
 | |
|         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
 | |
|         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'
 | |
|     -t, --title
 | |
|     --no-title
 | |
|         Afficher (resp. ne pas afficher) chaque correspondance avant de lancer
 | |
|         la commande. Par défaut, l'affichage est effectué."
 | |
| }
 | |
| 
 | |
| basedir=
 | |
| match=auto
 | |
| changedir=
 | |
| parentdir=
 | |
| expand=1
 | |
| title=1
 | |
| args=(+
 | |
|     --help '$exit_with display_help'
 | |
|     -b:,--basedir: basedir=
 | |
|     -d,--dir match=dir
 | |
|     -f,-file match=file
 | |
|     -a,--all match=all
 | |
|     -p,--parent parentdir=1
 | |
|     -g,--go changedir=1
 | |
|     -s,--string match=string
 | |
|     -x,--expand expand=1
 | |
|     -n,--no-expand expand=
 | |
|     -t,--title title=1
 | |
|     --no-title title=
 | |
| )
 | |
| parse_args "$@"; set -- "${args[@]}"
 | |
| 
 | |
| if [ "$match" == auto ]; then
 | |
|     if [ -n "$changedir" ]; then
 | |
|         match=dir
 | |
|     else
 | |
|         match=all
 | |
|     fi
 | |
| fi
 | |
| 
 | |
| varexpr="$1"; shift
 | |
| splitfsep2 "$varexpr" = varname expr
 | |
| [ -n "$varname" ] || varname=item
 | |
| [ -n "$expr" ] || expr="*"
 | |
| 
 | |
| cmd=("$@")
 | |
| if [ ${#cmd[*]} -eq 0 ]; then
 | |
|     if [ -n "$expand" ]; then
 | |
|         cmd=(echo %item)
 | |
|     else
 | |
|         cmd=('echo "$item"')
 | |
|     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"
 | |
|     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
 | |
|     (
 | |
|         if [ -n "$changedir" ]; then
 | |
|             if [ -f "$item" ]; then
 | |
|                 parentdir=1
 | |
|             elif [ ! -d "$item" ]; then
 | |
|                 ewarn "$item: n'est pas un répertoire"
 | |
|                 changedir=
 | |
|             fi
 | |
|         fi
 | |
|         if [ -n "$parentdir" ]; then
 | |
|             cd "$dir"
 | |
|             item="$name"
 | |
|         elif [ -n "$changedir" ]; then
 | |
|             cd "$item"
 | |
|             item=.
 | |
|         fi
 | |
|         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[@] \
 | |
| '
 | |
| function replace_vars(src,             re, vs, dest) {
 | |
|   re = "(%(file|dir|name|basename|ext|dotext|index|" varname "))"
 | |
|   while (src != "") {
 | |
|     if (match(src, "%%") != 0) {
 | |
|       dest = dest substr(src, 1, RSTART)
 | |
|       src = substr(src, RSTART + RLENGTH)
 | |
|     } else if (match(src, "%" re) != 0) {
 | |
|       dest = dest substr(src, 1, RSTART)
 | |
|       src = substr(src, RSTART + RLENGTH)
 | |
|     } else if (match(src, re, vs) != 0) {
 | |
|       dest = dest substr(src, 1, RSTART - 1)
 | |
|       src = substr(src, RSTART + RLENGTH)
 | |
|     } else {
 | |
|       break
 | |
|     }
 | |
|     var = vs[2]
 | |
|     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
 | |
| }
 | |
| BEGIN {
 | |
|   for (i=1; i<=cmd_count; i++) {
 | |
|     arg = replace_vars(cmd[i])
 | |
|     print arg
 | |
|   }
 | |
| }')"
 | |
|             eval "export $(echo_setv "$varname" "$item")"
 | |
|             "${cmd[@]}"
 | |
|         else
 | |
|             eval "export $(echo_setv "$varname" "$item"); ${cmd[*]}"
 | |
|         fi
 | |
|     )
 | |
|     [ -n "$title" ] && eend "$item"
 | |
|     let index=$index+1
 | |
| done
 |