fnconv accepte une liste de commandes
This commit is contained in:
parent
d8453b3d84
commit
1fccb5a900
313
fnconv
313
fnconv
|
@ -1,100 +1,237 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
# -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8
|
# -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8
|
||||||
|
|
||||||
function display_help() {
|
|
||||||
uecho "$scriptname: renommer des fichiers en changeant leur encoding
|
|
||||||
|
|
||||||
USAGE
|
|
||||||
$scriptname [-f src_enc] [ -t dest_enc] [/path/to/file]
|
|
||||||
|
|
||||||
OPTIONS
|
|
||||||
-f from
|
|
||||||
Encoding source. Si n'est pas spécifié ou vaut 'detect', l'encoding est
|
|
||||||
autodétecté.
|
|
||||||
-t to
|
|
||||||
Encoding destination. Doit être spécifié.
|
|
||||||
-N Ne pas optimiser le calcul de l'encoding. Cette option n'est valide que
|
|
||||||
si -f n'est pas spécifié. On assume que tous les noms de fichiers n'ont
|
|
||||||
pas le même encoding. L'encoding from est donc recalculé à chaque fois.
|
|
||||||
-r inverser from et to, qui doivent être tous les deux spécifiés."
|
|
||||||
}
|
|
||||||
|
|
||||||
if [ "$#" -eq 1 -a "$1" == --nutools-makelinks ]; then
|
|
||||||
# créer les liens
|
|
||||||
scriptname="$(basename "$0")"
|
|
||||||
for destenc in latin1 utf8; do
|
|
||||||
ln -s "$scriptname" "${scriptname}2$destenc"
|
|
||||||
done
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
source "$(dirname "$0")/lib/ulib/ulib" || exit 1
|
source "$(dirname "$0")/lib/ulib/ulib" || exit 1
|
||||||
urequire DEFAULTS
|
urequire DEFAULTS
|
||||||
|
|
||||||
from=detect
|
function display_help() {
|
||||||
case "${scriptname#fnconv2}" in
|
uecho "$scriptname: renommer un fichier ou les fichiers d'un répertoire
|
||||||
utf8) to=utf-8;;
|
|
||||||
latin1) to=iso-8859-1;;
|
|
||||||
*) to=;;
|
|
||||||
esac
|
|
||||||
optimize=1
|
|
||||||
parse_opts "${PRETTYOPTS[@]}" \
|
|
||||||
--help '$exit_with display_help' \
|
|
||||||
-f: from= \
|
|
||||||
-t: to= \
|
|
||||||
-N optimize= \
|
|
||||||
-r reverse \
|
|
||||||
@ args -- "$@" && set -- "${args[@]}" || die "$args"
|
|
||||||
|
|
||||||
function fnconv() {
|
USAGE
|
||||||
# $1 = fichier à renommer
|
$scriptname [options] <file|dir> [cmds...]
|
||||||
local lfrom="$from" lto="$to"
|
|
||||||
local srcdir="$(dirname "$1")"
|
|
||||||
local srcname="$(basename "$1")"
|
|
||||||
if [ "$lfrom" == "detect" ]; then
|
|
||||||
lfrom="$("$scriptdir/lib/pywrapper" uencdetect.py "$srcname")"
|
|
||||||
if [ "$lfrom" == "Unknown" ]; then
|
|
||||||
eerror "$srcname: Impossible de déterminer l'encoding"
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
if [ -n "$optimize" ]; then
|
|
||||||
from="$(__norm_encoding "$lfrom")"
|
|
||||||
[ "$from" != "$to" ] && enote "Conversion $from --> $to"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
if [ -n "$optimize" -a "$from" == "$to" ]; then
|
|
||||||
die "Une conversion de $from à $to n'a pas de sens.
|
|
||||||
Veuillez re-essayer avec -N si nécessaire."
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -n "$reverse" ]; then
|
Une ou plusieurs commandes peuvent être spécifiées, séparées //
|
||||||
tmp="$lto"
|
La commande par défaut est 'fixcase'
|
||||||
lto="$lfrom"
|
|
||||||
lfrom="$tmp"
|
|
||||||
fi
|
|
||||||
|
|
||||||
local src="$(abspath "$srcdir/$srcname")"
|
OPTIONS
|
||||||
local dest
|
-N, --detect-always
|
||||||
dest="$srcdir/$(iconv -f "$lfrom" -t "$lto" <<<"$srcname")" || return 1
|
Pour la commande conv, ne pas optimiser le calcul de l'encoding. Cette
|
||||||
dest="$(abspath "$dest")"
|
option n'est valide que si src_enc n'est pas spécifié. On assume que
|
||||||
if [ "$src" != "$dest" ]; then
|
tous les fichiers n'ont pas le même encoding: l'encoding src_enc est
|
||||||
ebegin "$(ppath "$src") --> $(basename "$dest")" \
|
donc recalculé à chaque fois.
|
||||||
mv "$src" "$dest"
|
-r, --reverse
|
||||||
fi
|
Pour la commande conv, inverser src_enc et dest_enc, qui doivent être
|
||||||
src="$dest"
|
tous les deux spécifiés.
|
||||||
if [ -d "$src" ]; then
|
|
||||||
etitle -s "$(ppath "$src")"
|
COMMANDES
|
||||||
local subsrcs subsrc
|
conv dest_enc [src_enc]
|
||||||
array_lsall subsrcs "$src"
|
Convertir le nom du fichier dans un autre encoding.
|
||||||
for subsrc in "${subsrcs[@]}"; do
|
dest_enc est l'encoding destination. Il doit être spécifié.
|
||||||
fnconv "$subsrc"
|
src_enc est l'encoding source. S'il n'est pas spécifié ou vaut 'detect',
|
||||||
done
|
il est autodétecté.
|
||||||
eend
|
utf8 [src_enc]
|
||||||
|
Equivalent à conv utf8 src_enc
|
||||||
|
latin1 [src_enc]
|
||||||
|
Equivalent à conv latin1 src_enc
|
||||||
|
noaccents
|
||||||
|
Transformer les caractères accentués en caractères non accentués
|
||||||
|
lowercase
|
||||||
|
Transfomer le nom en minuscule
|
||||||
|
uppercase
|
||||||
|
Transformer le nom en majuscule
|
||||||
|
fixcase
|
||||||
|
Transformer le nom en minuscule s'il est entièrement en majuscule"
|
||||||
|
}
|
||||||
|
|
||||||
|
function _lowercase() {
|
||||||
|
evalx cat // strlower
|
||||||
|
}
|
||||||
|
function _uppercase() {
|
||||||
|
evalx cat // strupper
|
||||||
|
}
|
||||||
|
function _fixcase() {
|
||||||
|
local actual upper
|
||||||
|
setx actual=cat
|
||||||
|
setx upper=strupper "$actual"
|
||||||
|
if [ "$actual" == "$upper" ]; then
|
||||||
|
strlower "$actual"
|
||||||
|
else
|
||||||
|
echo "$actual"
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
[ -n "$to" ] || die "Il faut spécifier l'encoding de destination"
|
function detect_enc() {
|
||||||
to="$(__norm_encoding "$to")"
|
local filename enc
|
||||||
for src in "$@"; do
|
if [ -f "$1" ]; then
|
||||||
fnconv "$src"
|
setx filename=basename -- "$1"
|
||||||
|
elif [ -d "$1" ]; then
|
||||||
|
local -a files
|
||||||
|
setx -a files=evalp find "$1" // head -n1
|
||||||
|
if [ ${#files[*]} -gt 0 ]; then
|
||||||
|
setx filename=basename -- "${files[0]}"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
setx enc="$scriptdir/lib/pywrapper" uencdetect.py "$filename"
|
||||||
|
echo "$enc"
|
||||||
|
[ "$enc" != Unknown ]
|
||||||
|
}
|
||||||
|
|
||||||
|
function before_parse_cmd() {
|
||||||
|
case "$1" in
|
||||||
|
conv)
|
||||||
|
if [ -n "$OPTIMIZE_CONV" ]; then
|
||||||
|
local to="$2"
|
||||||
|
[ -n "$to" ] && setx CONV_TO=__norm_encoding "$to"
|
||||||
|
|
||||||
|
local from="${3:-detect}"
|
||||||
|
if [ "$from" == "detect" ]; then
|
||||||
|
setx from=detect_enc "$FILE"
|
||||||
|
if [ "$from" == "Unknown" ]; then
|
||||||
|
echo "$FILE: Impossible de détecter l'encoding"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
[ -n "$from" ] && setx CONV_FROM=__norm_encoding "$from"
|
||||||
|
OPTIMIZE_CONV=
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
function iconv_detect() {
|
||||||
|
local to="$1"; shift
|
||||||
|
local from
|
||||||
|
if setx from=detect_enc "$FILE"; then
|
||||||
|
if [ -n "$REVERSE_CONV" ]; then
|
||||||
|
local tmp="$to"
|
||||||
|
to="$from"
|
||||||
|
from="$tmp"
|
||||||
|
fi
|
||||||
|
iconv -f "$from" -t "$to" "$@"
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
cat
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
function parse_cmd() {
|
||||||
|
local cmd="$1"; shift
|
||||||
|
local -a args
|
||||||
|
case "$cmd" in
|
||||||
|
utf8) parse_cmd conv utf8 "$@";;
|
||||||
|
latin1) parse_cmd conv latin1 "$@";;
|
||||||
|
conv)
|
||||||
|
local to="$CONV_TO" from="$CONV_FROM"
|
||||||
|
[ -n "$to" ] || to="$1"; shift
|
||||||
|
[ -f "$from" ] || from="${1:-detect}"; shift
|
||||||
|
|
||||||
|
if [ -z "$to" ]; then
|
||||||
|
echo "conv: vous devez spécifier l'encoding destination"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
setx to=__norm_encoding "$to"
|
||||||
|
if [ "$from" == "detect" ]; then
|
||||||
|
qvals iconv_detect "$to" "$@"
|
||||||
|
else
|
||||||
|
setx from=__norm_encoding "$from"
|
||||||
|
if [ "$from" == "$to" ]; then
|
||||||
|
echo "Une conversion de $from à $to n'a pas de sens. Veuillez re-essayer avec -N si nécessaire."
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
if [ -n "$REVERSE_CONV" ]; then
|
||||||
|
local tmp="$to"
|
||||||
|
to="$from"
|
||||||
|
from="$tmp"
|
||||||
|
fi
|
||||||
|
qvals iconv -f "$from" -t "$to" "$@"
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
noaccents|noa|fixchars) echo _noaccents;;
|
||||||
|
lowercase|lower|l) echo _lowercase;;
|
||||||
|
uppercase|upper|U) echo _uppercase;;
|
||||||
|
fixcase|fix|c) echo _fixcase;;
|
||||||
|
*)
|
||||||
|
echo "$cmd: commande invalide"
|
||||||
|
return 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
function fnconv() {
|
||||||
|
local dir oldname newname
|
||||||
|
setx dir=dirname -- "$FILE"
|
||||||
|
setx oldname=basename -- "$FILE"
|
||||||
|
setx newname=eval "$CMD" <<<"$oldname"
|
||||||
|
|
||||||
|
if [ -d "$FILE" ]; then
|
||||||
|
if [ "$newname" != "$oldname" ]; then
|
||||||
|
etitle "$(ppath "$FILE") --> $newname"
|
||||||
|
mv "$FILE" "$dir/$newname" || die
|
||||||
|
FILE="$dir/$newname"
|
||||||
|
else
|
||||||
|
etitle "$(ppath "$FILE")"
|
||||||
|
fi
|
||||||
|
local -a sfiles
|
||||||
|
array_lsall sfiles "$FILE"
|
||||||
|
for FILE in "${sfiles[@]}"; do
|
||||||
|
fnconv
|
||||||
|
done
|
||||||
|
eend
|
||||||
|
else
|
||||||
|
if [ "$newname" != "$oldname" ]; then
|
||||||
|
estep "$oldname --> $newname"
|
||||||
|
mv "$FILE" "$dir/$newname" || die
|
||||||
|
FILE="$dir/$newname"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
OPTIMIZE_CONV=1
|
||||||
|
REVERSE_CONV=
|
||||||
|
CONV_FROM=
|
||||||
|
CONV_TO=
|
||||||
|
parse_opts "${PRETTYOPTS[@]}" \
|
||||||
|
--help '$exit_with display_help' \
|
||||||
|
-N,--detect-always OPTIMIZE_CONV= \
|
||||||
|
-r,--reverse REVERSE_CONV=1 \
|
||||||
|
@ args -- "$@" && set -- "${args[@]}" || die "$args"
|
||||||
|
|
||||||
|
FILE="$1"; shift
|
||||||
|
[ "$FILE" == - ] && FILE=/dev/stdin
|
||||||
|
if [ "$FILE" != /dev/stdin ]; then
|
||||||
|
[ -e "$FILE" ] || die "$FILE: fichier introuvable"
|
||||||
|
fi
|
||||||
|
|
||||||
|
[ $# -gt 0 ] || set -- fixcase # commande par défaut
|
||||||
|
|
||||||
|
CMD= # la commande finale à lancer pour convertir le flux
|
||||||
|
while [ $# -gt 0 ]; do
|
||||||
|
args=()
|
||||||
|
while [ $# -gt 0 ]; do
|
||||||
|
arg="$1"; shift
|
||||||
|
if [ "$arg" == // ]; then
|
||||||
|
break
|
||||||
|
elif [ "${arg%//}" != "$arg" ]; then
|
||||||
|
local tmp="${arg%//}"
|
||||||
|
if [ -z "${tmp//\\/}" ]; then
|
||||||
|
arg="${arg#\\}"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
args=("${args[@]}" "$arg")
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ ${#args[*]} -gt 0 ]; then
|
||||||
|
before_parse_cmd "${args[@]}"
|
||||||
|
setx cmd=parse_cmd "${args[@]}" || die "$cmd"
|
||||||
|
CMD="${CMD:+$CMD | }$cmd"
|
||||||
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
|
if [ "$FILE" == /dev/stdin ]; then
|
||||||
|
eval "$CMD"
|
||||||
|
elif [ -f "$FILE" -o -d "$FILE" ]; then
|
||||||
|
fnconv
|
||||||
|
else
|
||||||
|
die "$FILE: fichier invalide"
|
||||||
|
fi
|
||||||
|
|
Loading…
Reference in New Issue