2016-05-10 22:23:15 +04:00
|
|
|
#!/bin/bash
|
|
|
|
# -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8
|
2016-08-30 13:47:31 +04:00
|
|
|
|
|
|
|
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
|
|
|
|
|
2016-05-10 22:23:15 +04:00
|
|
|
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/~~
|
2016-08-30 13:47:31 +04:00
|
|
|
--string
|
|
|
|
Remplacer dans chaque argument le placeholder par la date et afficher le
|
|
|
|
résultat.
|
2016-05-10 22:23:15 +04:00
|
|
|
-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.
|
2016-08-30 13:47:31 +04:00
|
|
|
-@, --force-date DATE
|
|
|
|
Dans le nom spécifié, si la date est déjà présente, 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.
|
2017-04-21 16:32:54 +04:00
|
|
|
S'il y a au moins 2 arguments et si le premier ou le dernier argument
|
|
|
|
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é aussi.
|
|
|
|
Les commandes suivantes sont équivalentes:
|
|
|
|
$scriptname -@ d/m/y file
|
|
|
|
$scriptname d/m/y file
|
|
|
|
$scriptname file @d/m/y
|
2016-05-10 22:23:15 +04:00
|
|
|
-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
|
2016-08-30 13:47:31 +04:00
|
|
|
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"
|
2016-05-10 22:23:15 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
function create() {
|
|
|
|
case "$create" in
|
|
|
|
file) touch "$1";;
|
|
|
|
dir) mkdir -p "$1";;
|
|
|
|
esac
|
|
|
|
}
|
|
|
|
function have_ph() {
|
|
|
|
[[ "$1" == *"$placeholder"* ]]
|
|
|
|
}
|
|
|
|
function replace_ph() {
|
2016-08-30 13:47:31 +04:00
|
|
|
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)
|
|
|
|
}
|
|
|
|
|
2016-05-10 22:23:15 +04:00
|
|
|
BEGIN {
|
2016-08-30 13:47:31 +04:00
|
|
|
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)
|
|
|
|
}
|
2016-05-10 22:23:15 +04:00
|
|
|
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) {
|
2016-08-30 13:47:31 +04:00
|
|
|
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
|
|
|
|
}
|
|
|
|
}
|
2016-05-10 22:23:15 +04:00
|
|
|
} 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) {
|
2016-08-30 13:47:31 +04:00
|
|
|
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
|
|
|
|
}
|
|
|
|
}
|
2016-05-10 22:23:15 +04:00
|
|
|
} else {
|
|
|
|
print dir substr(name, 1, pos - 1) date substr(name, pos + length(ph))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}' <<<"$1"
|
|
|
|
}
|
|
|
|
|
|
|
|
action=create
|
|
|
|
create=
|
2016-08-30 13:47:31 +04:00
|
|
|
case "$scriptname" in
|
|
|
|
ddir) action=create; create=dir;;
|
|
|
|
dfile) action=create; create=file;;
|
|
|
|
dcopy) action=copy;;
|
|
|
|
dmove) action=move;;
|
|
|
|
dcmd) action=cmd;;
|
|
|
|
esac
|
2016-05-10 22:23:15 +04:00
|
|
|
placeholder=
|
2017-04-21 16:32:54 +04:00
|
|
|
auto_force_date=1
|
2016-08-30 13:47:31 +04:00
|
|
|
force_date=
|
2016-05-10 22:23:15 +04:00
|
|
|
format=
|
2016-08-30 13:47:31 +04:00
|
|
|
autof=
|
2016-05-10 22:23:15 +04:00
|
|
|
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 \
|
2016-08-30 13:47:31 +04:00
|
|
|
--string action=string \
|
2016-05-10 22:23:15 +04:00
|
|
|
-P:,--placeholder: placeholder= \
|
2017-04-21 16:32:54 +04:00
|
|
|
--no-auto-force-date auto_force_date= \
|
2016-08-30 13:47:31 +04:00
|
|
|
-@:,--force-date: force_date= \
|
2016-05-10 22:23:15 +04:00
|
|
|
-F:,--format: format= \
|
2016-08-30 13:47:31 +04:00
|
|
|
-s,--short '$format=YYMMDD; autof=1' \
|
|
|
|
-l,--long '$format=YYYYMMDD; autof=1' \
|
2016-05-10 22:23:15 +04:00
|
|
|
--autof autof=1 \
|
|
|
|
@ args -- "$@" && set -- "${args[@]}" || die "$args"
|
|
|
|
|
2017-04-21 16:32:54 +04:00
|
|
|
if [ $# -gt 1 -a -z "$force_date" -a -n "$auto_force_date" ]; then
|
|
|
|
# si le premier ou le dernier argument ressemblent à une date
|
|
|
|
f="$1"; f2="${f#@}"
|
|
|
|
l="${@:$#}"; l2="${l#@}"
|
|
|
|
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 [[ "$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
|
|
|
|
|
2016-05-10 22:23:15 +04:00
|
|
|
[ -n "$create" ] || create=file
|
|
|
|
[ -n "$placeholder" ] || placeholder="~~"
|
2016-08-30 13:47:31 +04:00
|
|
|
[ -n "$force_date" ] && setx force_date=parse_date "$force_date"
|
|
|
|
if [ -z "$format" ]; then
|
2016-05-10 22:23:15 +04:00
|
|
|
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
|
|
|
|
check_interaction -c && evalx qvals "${args[@]}" "$arg" // estepi "Commande:"
|
2016-08-30 13:47:31 +04:00
|
|
|
setx arg=replace_ph "$arg" "$force_date"
|
2016-05-10 22:23:15 +04:00
|
|
|
read_value "Veuillez confirmer le nom" arg "$arg"
|
|
|
|
found=1
|
|
|
|
fi
|
|
|
|
args=("${args[@]}" "$arg")
|
|
|
|
done
|
|
|
|
if [ -z "$found" ]; then
|
2016-08-30 13:47:31 +04:00
|
|
|
setx arg=replace_ph "" "$force_date"
|
2016-05-10 22:23:15 +04:00
|
|
|
read_value "Veuillez entrer le nom du fichier" arg "$arg"
|
|
|
|
args=("${args[@]}" "$arg")
|
|
|
|
fi
|
|
|
|
|
|
|
|
if show_debug; then
|
2016-08-30 13:47:31 +04:00
|
|
|
evalx qvals "${args[@]}" // edebug "Commande effective:"
|
2016-05-10 22:23:15 +04:00
|
|
|
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
|
2016-08-30 13:47:31 +04:00
|
|
|
setx src=abspath "$src"
|
2016-05-10 22:23:15 +04:00
|
|
|
setx srcname=basename -- "$src"
|
|
|
|
if [ -e "$src" ]; then
|
2016-08-30 13:47:31 +04:00
|
|
|
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"
|
2016-05-10 22:23:15 +04:00
|
|
|
read_value "Veuillez confirmer le nom" destname "$destname"
|
2016-08-30 13:47:31 +04:00
|
|
|
|
|
|
|
setx dest=abspath "$destdir/$destname"
|
|
|
|
[ "$src" != "$dest" ] && "${cmd[@]}" "$src" "$destdir/$destname"
|
2016-05-10 22:23:15 +04:00
|
|
|
else
|
|
|
|
ewarn "$src: fichier introuvable"
|
|
|
|
fi
|
|
|
|
done
|
|
|
|
|
|
|
|
elif [ "$action" == create ]; then
|
|
|
|
if [ $# -gt 0 ]; then
|
|
|
|
for src in "$@"; do
|
2016-08-30 13:47:31 +04:00
|
|
|
setx src=abspath "$src"
|
2016-05-10 22:23:15 +04:00
|
|
|
setx dir=dirname -- "$src"
|
|
|
|
setx srcname=basename -- "$src"
|
|
|
|
if [ -e "$src" ]; then
|
2016-08-30 13:47:31 +04:00
|
|
|
estep "Renommage de $(ppath "$src")"
|
|
|
|
setx destname=replace_ph "$srcname" "$force_date"
|
|
|
|
setx dest=abspath "$dir/$destname"
|
|
|
|
[ "$src" != "$dest" ] || ewarn "La source et la destination sont identiques"
|
2016-05-10 22:23:15 +04:00
|
|
|
read_value "Veuillez confirmer le nom" destname "$destname"
|
2016-08-30 13:47:31 +04:00
|
|
|
|
|
|
|
setx dest=abspath "$dir/$destname"
|
|
|
|
[ "$src" != "$dest" ] && mv -i "$src" "$dir/$destname"
|
2016-05-10 22:23:15 +04:00
|
|
|
else
|
2016-08-30 13:47:31 +04:00
|
|
|
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
|
2016-05-10 22:23:15 +04:00
|
|
|
read_value "Veuillez confirmer le nom" destname "$destname"
|
2016-08-30 13:47:31 +04:00
|
|
|
|
|
|
|
setx dest=abspath "$dir/$destname"
|
2016-05-10 22:23:15 +04:00
|
|
|
create "$dir/$destname"
|
|
|
|
fi
|
|
|
|
done
|
|
|
|
else
|
2016-08-30 13:47:31 +04:00
|
|
|
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"
|
2016-05-10 22:23:15 +04:00
|
|
|
create "$destname"
|
|
|
|
fi
|
|
|
|
|
2016-08-30 13:47:31 +04:00
|
|
|
elif [ "$action" == string ]; then
|
|
|
|
if [ $# -gt 0 ]; then
|
|
|
|
for string in "$@"; do
|
|
|
|
replace_ph "$string" "$force_date"
|
|
|
|
done
|
|
|
|
else
|
|
|
|
replace_ph "" "$force_date"
|
|
|
|
fi
|
|
|
|
|
2016-05-10 22:23:15 +04:00
|
|
|
else
|
|
|
|
die "$action: action non implémentée"
|
|
|
|
fi
|