431 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			Bash
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			431 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			Bash
		
	
	
		
			Executable File
		
	
	
	
	
#!/bin/bash
 | 
						|
# -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8
 | 
						|
 | 
						|
TOOLS=(ddir dfile dcopy dmove dcmd)
 | 
						|
if [ "$#" -eq 1 -a "$1" == --nutools-makelinks ]; then
 | 
						|
    # créer les liens
 | 
						|
    scriptname="$(basename "$0")"
 | 
						|
    for tool in "${TOOLS[@]}"; do
 | 
						|
        ln -s "$scriptname" "$tool"
 | 
						|
    done
 | 
						|
    exit 0
 | 
						|
fi
 | 
						|
 | 
						|
source "$(dirname "$0")/lib/ulib/ulib" || exit 1
 | 
						|
urequire DEFAULTS
 | 
						|
 | 
						|
function display_help() {
 | 
						|
    uecho "$scriptname: manipuler des noms de fichier pour les dater
 | 
						|
 | 
						|
USAGE
 | 
						|
    $scriptname (FILE|DIR)s...
 | 
						|
    $scriptname -k SRCs... [DESTDIR]
 | 
						|
    $scriptname -m SRCs... [DESTDIR]
 | 
						|
    $scriptname -c COMMAND [ARGs...]
 | 
						|
 | 
						|
OPTIONS
 | 
						|
    --create-or-rename
 | 
						|
        Créer un nouveau fichier (option -f) ou créer un nouveau répertoire
 | 
						|
        (option -d), ou renommer un fichier existant sans le changer de
 | 
						|
        répertoire. C'est l'option par défaut.
 | 
						|
    -f, --create-file
 | 
						|
        Créer un nouveau fichier. Cette option est ignorée si le fichier ou le
 | 
						|
        répertoire spécifié existe. C'est la valeur par défaut
 | 
						|
    -d, --create-dir
 | 
						|
        Créer un nouveau répertoire. Cette option est ignorée si le fichier ou
 | 
						|
        le répertoire spécifié existe.
 | 
						|
    -k, --copy
 | 
						|
        Copier le fichier SRC vers la destination DESTDIR qui vaut par défaut le
 | 
						|
        répertoire courant si un seul fichier source est spécifié. Si plusieurs
 | 
						|
        fichiers sources sont spécifiés, il faut absolument spécifier un
 | 
						|
        répertoire destination. Dans la destination, les fichiers sont nommés
 | 
						|
        avec la date en préfixe.
 | 
						|
    -m, --move
 | 
						|
        Déplacer le fichier SRC vers la destination DESTDIR qui vaut par défaut
 | 
						|
        le répertoire courant si un seul fichier source est spécifié. Si
 | 
						|
        plusieurs fichiers sources sont spécifiés, il faut absolument spécifier
 | 
						|
        un répertoire destination. Dans la destination, les fichiers sont nommés
 | 
						|
        avec la date en préfixe.
 | 
						|
    -c, --cmd
 | 
						|
        Les arguments sont une commande à lancer. Dans les argument, PLACEHOLDER
 | 
						|
        est remplacé par la date. Si le PLACEHOLDER n'est trouvé dans aucun des
 | 
						|
        arguments, alors ajouter la date à la fin de la commande. Par exemple,
 | 
						|
        voici comment émuler l'option -k
 | 
						|
            $scriptname -c cp src dest/~~
 | 
						|
    --string
 | 
						|
        Remplacer dans chaque argument le placeholder par la date et afficher le
 | 
						|
        résultat.
 | 
						|
    -P, --placeholder PLACEHOLDER
 | 
						|
        Dans le nom spécifié, remplacer PLACEHOLDER par la date. Par défaut,
 | 
						|
        PLACEHOLDER vaut ~~. Si le nom spécifié ne contient pas le PLACEHOLDER,
 | 
						|
        il est placé au début.
 | 
						|
    -@, --force-date DATE
 | 
						|
        Si une date du format attendu est déjà présente dans le nom du fichier,
 | 
						|
        forcer son remplacement par la valeur spécifiée. Par défaut, le fichier
 | 
						|
        n'est pas modifié si la date est déjà présente.
 | 
						|
        Si le premier ou le dernier argument de ce script ressemblent à une date
 | 
						|
        (ie. d/m[/y] ou @d[/m[/y]]) et qu'aucun fichier de ce nom n'existe dans
 | 
						|
        le répertoire courant, activer automatiquement cette option, sauf si
 | 
						|
        l'option --no-auto-force-date est spécifiée aussi. Ainsi, les commandes
 | 
						|
        suivantes sont équivalentes:
 | 
						|
            $scriptname -@ d/m/y file
 | 
						|
            $scriptname d/m/y file
 | 
						|
            $scriptname file @d/m/y
 | 
						|
    -F, --format FORMAT
 | 
						|
        Spécifier le format de la date à insérer dans le nom du fichier. Par
 | 
						|
        défaut, FORMAT vaut 'YYMMDD-'
 | 
						|
        Les formats valides sont:
 | 
						|
            YYYY année sur 4 chiffres
 | 
						|
            YY   année sur 2 chiffres
 | 
						|
            MM   mois sur 2 chiffres
 | 
						|
            DD   jour sur 2 chiffres
 | 
						|
        Tous les autres caractères sont pris tels-quels
 | 
						|
    -s, --short
 | 
						|
        Equivalent à -F YYMMDD --autof
 | 
						|
    -l, --long
 | 
						|
        Equivalent à -F YYYMMDD --autof
 | 
						|
    --autof
 | 
						|
        Option non (pas encore) documentée"
 | 
						|
}
 | 
						|
 | 
						|
function create() {
 | 
						|
    case "$create" in
 | 
						|
    file) touch "$1";;
 | 
						|
    dir) mkdir -p "$1";;
 | 
						|
    esac
 | 
						|
}
 | 
						|
function have_ph() {
 | 
						|
    [[ "$1" == *"$placeholder"* ]]
 | 
						|
}
 | 
						|
function replace_ph() {
 | 
						|
    local fy fm fd
 | 
						|
    if [ -n "$force_date" ]; then
 | 
						|
        fd="${force_date:0:2}"
 | 
						|
        fm="${force_date:3:2}"
 | 
						|
        fy="${force_date:6:4}"
 | 
						|
    fi
 | 
						|
    awkrun ph="$placeholder" \
 | 
						|
           force_date="$force_date" fy:str="$fy" fm:str="$fm" fd:str="$fd" \
 | 
						|
           format="$format" autof:int="$autof" '
 | 
						|
function short2long(s,        cy, py, sy, ly) {
 | 
						|
  cy = strftime("%Y") + 0
 | 
						|
  cy = cy - cy % 100
 | 
						|
  py = cy - 100
 | 
						|
  sy = substr(s, 1, 2) + 0
 | 
						|
  if (sy >= 80) ly = py + sy
 | 
						|
  else ly = cy + sy
 | 
						|
  return ly substr(s, 3)
 | 
						|
}
 | 
						|
 | 
						|
BEGIN {
 | 
						|
  if (format ~ /YYYYMMDD/) type = "long"
 | 
						|
  else if (format ~ /YYMMDD/) type = "short"
 | 
						|
  else type = "custom"
 | 
						|
 | 
						|
  if (force_date != "") {
 | 
						|
    gsub(/%/, "%%", format)
 | 
						|
    gsub(/YYYY/, fy, format)
 | 
						|
    gsub(/YY/, substr(fy, 3, 2), format)
 | 
						|
    gsub(/MM/, fm, format)
 | 
						|
    gsub(/DD/, fd, format)
 | 
						|
  } else {
 | 
						|
    gsub(/%/, "%%", format)
 | 
						|
    gsub(/YYYY/, "%Y", format)
 | 
						|
    gsub(/YY/, "%y", format)
 | 
						|
    gsub(/MM/, "%m", format)
 | 
						|
    gsub(/DD/, "%d", format)
 | 
						|
  }
 | 
						|
  date = strftime(format)
 | 
						|
}
 | 
						|
{
 | 
						|
  if (index($0, "/") != 0) {
 | 
						|
    match($0, /\/[^/]*$/)
 | 
						|
    dir = substr($0, 1, RSTART)
 | 
						|
    name = substr($0, RSTART + 1)
 | 
						|
  } else {
 | 
						|
    dir = ""
 | 
						|
    name = $0
 | 
						|
  }
 | 
						|
 | 
						|
  if (autof) {
 | 
						|
    pos = index(name, ph)
 | 
						|
    if (pos == 0) {
 | 
						|
      if (force_date != "") {
 | 
						|
        if (type == "long") {
 | 
						|
          if (name ~ /^[0-9]{8}/) {
 | 
						|
            name = substr(name, 9)
 | 
						|
            print dir date name
 | 
						|
          } else if (name ~ /^[0-9]{6}/) {
 | 
						|
            name = substr(name, 7)
 | 
						|
            print dir date name
 | 
						|
          } else {
 | 
						|
            print dir date "-" name
 | 
						|
          }
 | 
						|
        } else if (type == "short") {
 | 
						|
          if (name ~ /^[0-9]{8}/) {
 | 
						|
            name = substr(name, 9)
 | 
						|
            print dir date name
 | 
						|
          } else if (name ~ /^[0-9]{6}/) {
 | 
						|
            name = substr(name, 7)
 | 
						|
            print dir date name
 | 
						|
          } else {
 | 
						|
            print dir date "-" name
 | 
						|
          }
 | 
						|
        } else if (type == "custom") {
 | 
						|
          print dir date "-" name
 | 
						|
        }
 | 
						|
      } else {
 | 
						|
        if (type == "long") {
 | 
						|
          if (name ~ /^[0-9]{8}/) print dir name
 | 
						|
          else if (name ~ /^[0-9]{6}/) print dir short2long(name)
 | 
						|
          else print dir date "-" name
 | 
						|
        } else if (type == "short") {
 | 
						|
          if (name ~ /^[0-9]{8}/) print dir substr(name, 3)
 | 
						|
          else if (name ~ /^[0-9]{6}/) print dir name
 | 
						|
          else print dir date "-" name
 | 
						|
        } else if (type == "custom") {
 | 
						|
          print dir date "-" name
 | 
						|
        }
 | 
						|
      }
 | 
						|
    } else if (pos == 1) {
 | 
						|
      print dir date "-" substr(name, length(ph) + 1)
 | 
						|
    } else if (pos == length(name) - length(ph) + 1) {
 | 
						|
      print dir substr(name, 1, length(name) - length(ph)) "-" date
 | 
						|
    } else {
 | 
						|
      print dir substr(name, 1, pos - 1) date substr(name, pos + length(ph))
 | 
						|
    }
 | 
						|
  } else {
 | 
						|
    pos = index(name, ph)
 | 
						|
    if (pos == 0) {
 | 
						|
      if (force_date != "") {
 | 
						|
        if (type == "long") {
 | 
						|
          if (name ~ /^[0-9]{8}/) name = substr(name, 9)
 | 
						|
          print dir date name
 | 
						|
        } else if (type == "short") {
 | 
						|
          if (name ~ /^[0-9]{6}/) name = substr(name, 7)
 | 
						|
          print dir date name
 | 
						|
        } else if (type == "custom") {
 | 
						|
          print dir date name
 | 
						|
        }
 | 
						|
      } else {
 | 
						|
        if (type == "long") {
 | 
						|
          if (name ~ /^[0-9]{8}/) print dir name
 | 
						|
          else print dir date name
 | 
						|
        } else if (type == "short") {
 | 
						|
          if (name ~ /^[0-9]{6}/) print dir name
 | 
						|
          else print dir date name
 | 
						|
        } else if (type == "custom") {
 | 
						|
          print dir date name
 | 
						|
        }
 | 
						|
      }
 | 
						|
    } else {
 | 
						|
      print dir substr(name, 1, pos - 1) date substr(name, pos + length(ph))
 | 
						|
    }
 | 
						|
  }
 | 
						|
}' <<<"$1"
 | 
						|
}
 | 
						|
 | 
						|
action=create
 | 
						|
create=
 | 
						|
case "$scriptname" in
 | 
						|
ddir) action=create; create=dir;;
 | 
						|
dfile) action=create; create=file;;
 | 
						|
dcopy) action=copy;;
 | 
						|
dmove) action=move;;
 | 
						|
dcmd) action=cmd;;
 | 
						|
esac
 | 
						|
cmd_quiet=
 | 
						|
placeholder=
 | 
						|
auto_force_date=1
 | 
						|
force_date=
 | 
						|
format=
 | 
						|
autof=
 | 
						|
parse_opts "${PRETTYOPTS[@]}" \
 | 
						|
    --help '$exit_with display_help' \
 | 
						|
    --create-or-rename action=create \
 | 
						|
    -d,--create-dir create=dir \
 | 
						|
    -f,--create-file create=file \
 | 
						|
    -k,--copy action=copy \
 | 
						|
    -m,--move action=move \
 | 
						|
    -c,--cmd action=cmd \
 | 
						|
    --string action=string \
 | 
						|
    --cmd-quiet cmd_quiet=1 \
 | 
						|
    -P:,--placeholder: placeholder= \
 | 
						|
    --no-auto-force-date auto_force_date= \
 | 
						|
    -@:,--force-date: force_date= \
 | 
						|
    -F:,--format: format= \
 | 
						|
    -s,--short '$format=YYMMDD; autof=1' \
 | 
						|
    -l,--long '$format=YYYYMMDD; autof=1' \
 | 
						|
    --autof autof=1 \
 | 
						|
    @ args -- "$@" && set -- "${args[@]}" || die "$args"
 | 
						|
 | 
						|
if [ -z "$force_date" -a -n "$auto_force_date" ]; then
 | 
						|
    # si le premier ou le dernier argument ressemblent à une date
 | 
						|
    f="$1"; f2="${f#@}"
 | 
						|
    if [[ "$f" == */* ]] && [ -z "${f//[0-9\/]}" -a ! -e "$f" ]; then
 | 
						|
        force_date="$f"
 | 
						|
        shift
 | 
						|
    elif [[ "$f" == @* ]] && [ -z "${f2//[0-9\/]}" -a ! -e "$f2" ]; then
 | 
						|
        force_date="$f2"
 | 
						|
        shift
 | 
						|
    elif [ $# -gt 1 ]; then
 | 
						|
        l="${@:$#}"; l2="${l#@}"
 | 
						|
        if [[ "$l" == */* ]] && [ -z "${l//[0-9\/]}" -a ! -e "$l" ]; then
 | 
						|
            force_date="$l"
 | 
						|
            set -- "${@:1:$(($# - 1))}"
 | 
						|
        elif [[ "$l" == @* ]] && [ -z "${l2//[0-9\/]}" -a ! -e "$l2" ]; then
 | 
						|
            force_date="$l2"
 | 
						|
            set -- "${@:1:$(($# - 1))}"
 | 
						|
        fi
 | 
						|
    fi
 | 
						|
fi
 | 
						|
 | 
						|
[ -n "$create" ] || create=file
 | 
						|
[ -n "$placeholder" ] || placeholder="~~"
 | 
						|
[ -n "$force_date" ] && setx force_date=parse_date "$force_date"
 | 
						|
if [ -z "$format" ]; then
 | 
						|
    format=YYMMDD
 | 
						|
    autof=1
 | 
						|
fi
 | 
						|
 | 
						|
if [ "$action" == cmd ]; then
 | 
						|
    # Il faut lancer une commande spécifiée
 | 
						|
    [ $# -gt 0 ] || set -- echo
 | 
						|
    args=()
 | 
						|
    found=
 | 
						|
    for arg in "$@"; do
 | 
						|
        if have_ph "$arg"; then
 | 
						|
            [ -z "$cmd_quiet" ] && check_interaction -c && evalx qvals "${args[@]}" "$arg" // estepi "Commande:"
 | 
						|
            setx arg=replace_ph "$arg" "$force_date"
 | 
						|
            read_value "Veuillez confirmer le nom" arg "$arg"
 | 
						|
            found=1
 | 
						|
        fi
 | 
						|
        args=("${args[@]}" "$arg")
 | 
						|
    done
 | 
						|
    if [ -z "$found" ]; then
 | 
						|
        setx arg=replace_ph "" "$force_date"
 | 
						|
        read_value "Veuillez entrer le nom du fichier" arg "$arg"
 | 
						|
        args=("${args[@]}" "$arg")
 | 
						|
    fi
 | 
						|
 | 
						|
    if show_debug; then
 | 
						|
        evalx qvals "${args[@]}" // edebug "Commande effective:"
 | 
						|
        ask_yesno "Voulez-vous continuer?" X || die
 | 
						|
    fi
 | 
						|
    "${args[@]}"
 | 
						|
 | 
						|
elif [ "$action" == copy -o "$action" == move ]; then
 | 
						|
    if [ $# -eq 0 ]; then
 | 
						|
        die "Vous devez spécifier les fichiers"
 | 
						|
    elif [ $# -eq 1 ]; then
 | 
						|
        src="$1"
 | 
						|
        destdir=.
 | 
						|
        srcs=("$src")
 | 
						|
    else
 | 
						|
        args=("$@")
 | 
						|
        setx destdir=last_value args
 | 
						|
        array_copy_firsts srcs args
 | 
						|
    fi
 | 
						|
    if [ ! -d "$destdir" ]; then
 | 
						|
        ewarn "$destdir: répertoire introuvable"
 | 
						|
        ask_yesno "Voulez-vous le créer?" X || die
 | 
						|
        mkdir -p "$destdir" || die
 | 
						|
    fi
 | 
						|
    if [ "$action" == copy ]; then
 | 
						|
        cmdinfo="Copie"
 | 
						|
        cmd=(cp -i)
 | 
						|
    elif [ "$action" == move ]; then
 | 
						|
        cmdinfo="Déplacement"
 | 
						|
        cmd=(mv -i)
 | 
						|
    fi
 | 
						|
    for src in "${srcs[@]}"; do
 | 
						|
        setx src=abspath "$src"
 | 
						|
        setx srcname=basename -- "$src"
 | 
						|
        if [ -e "$src" ]; then
 | 
						|
            estep "$cmdinfo de $(ppath "$src")"
 | 
						|
            setx destname=replace_ph "$srcname" "$force_date"
 | 
						|
            setx dest=abspath "$destdir/$destname"
 | 
						|
            [ "$src" != "$dest" ] || ewarn "La source et la destination sont identiques"
 | 
						|
            read_value "Veuillez confirmer le nom" destname "$destname"
 | 
						|
 | 
						|
            setx dest=abspath "$destdir/$destname"
 | 
						|
            [ "$src" != "$dest" ] && "${cmd[@]}" "$src" "$destdir/$destname"
 | 
						|
        else
 | 
						|
            ewarn "$src: fichier introuvable"
 | 
						|
        fi
 | 
						|
    done
 | 
						|
 | 
						|
elif [ "$action" == create ]; then
 | 
						|
    if [ $# -gt 0 ]; then
 | 
						|
        for src in "$@"; do
 | 
						|
            setx src=abspath "$src"
 | 
						|
            setx dir=dirname -- "$src"
 | 
						|
            setx srcname=basename -- "$src"
 | 
						|
            if [ -e "$src" ]; then
 | 
						|
                setx destname=replace_ph "$srcname" "$force_date"
 | 
						|
                setx dest=abspath "$dir/$destname"
 | 
						|
                confirm_do=1
 | 
						|
                if [ "$src" == "$dest" ]; then
 | 
						|
                    if [ -n "$force_date" ]; then
 | 
						|
                        ewarn "La source et la destination sont identiques"
 | 
						|
                    else
 | 
						|
                        estepi "$(ppath "$src"): aucun renommage nécessaire"
 | 
						|
                        confirm_do=
 | 
						|
                    fi
 | 
						|
                fi
 | 
						|
                if [ -n "$confirm_do" ]; then
 | 
						|
                    estep "Renommage de $(ppath "$src")"
 | 
						|
                    read_value "Veuillez confirmer le nom" destname "$destname"
 | 
						|
 | 
						|
                    setx dest=abspath "$dir/$destname"
 | 
						|
                    [ "$src" != "$dest" ] && mv -i "$src" "$dir/$destname"
 | 
						|
                fi
 | 
						|
            else
 | 
						|
                setx destname=replace_ph "$srcname" "$force_date"
 | 
						|
                setx dest=abspath "$dir/$destname"
 | 
						|
                if [ -d "$dest" ]; then
 | 
						|
                    ewarn "$srcname --> $(ppath "$dest"): répertoire existant"
 | 
						|
                elif [ -e "$dest" ]; then
 | 
						|
                    ewarn "$srcname --> $(ppath "$dest"): fichier existant"
 | 
						|
                else
 | 
						|
                    estep "$srcname --> Création de $(ppath "$dest")"
 | 
						|
                fi
 | 
						|
                read_value "Veuillez confirmer le nom" destname "$destname"
 | 
						|
 | 
						|
                setx dest=abspath "$dir/$destname"
 | 
						|
                create "$dir/$destname"
 | 
						|
            fi
 | 
						|
        done
 | 
						|
    else
 | 
						|
        setx destname=replace_ph "" "$force_date"
 | 
						|
        confirm_action=entrer
 | 
						|
        if [ -d "$destname" ]; then
 | 
						|
            ewarn "$destname: répertoire existant"
 | 
						|
            confirm_action=confirmer
 | 
						|
        elif [ -e "$destname" ]; then
 | 
						|
            ewarn "$destname: fichier existant"
 | 
						|
            confirm_action=confirmer
 | 
						|
        else
 | 
						|
            case "$create" in
 | 
						|
            file) estep "Création d'un nouveau fichier";;
 | 
						|
            dir) estep "Création d'un nouveau répertoire";;
 | 
						|
            esac
 | 
						|
        fi
 | 
						|
 | 
						|
        read_value "Veuillez $confirm_action le nom" destname "$destname"
 | 
						|
        create "$destname"
 | 
						|
    fi
 | 
						|
 | 
						|
elif [ "$action" == string ]; then
 | 
						|
    if [ $# -gt 0 ]; then
 | 
						|
        for string in "$@"; do
 | 
						|
            replace_ph "$string" "$force_date"
 | 
						|
        done
 | 
						|
    else
 | 
						|
        replace_ph "" "$force_date"
 | 
						|
    fi
 | 
						|
 | 
						|
else
 | 
						|
    die "$action: action non implémentée"
 | 
						|
fi
 |