nutools/fnconv

264 lines
7.4 KiB
Plaintext
Raw Permalink Normal View History

2013-08-27 15:14:44 +04:00
#!/bin/bash
# -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8
2014-10-12 22:54:49 +04:00
source "$(dirname "$0")/lib/ulib/ulib" || exit 1
urequire DEFAULTS
2013-08-27 15:14:44 +04:00
function display_help() {
2014-10-12 22:54:49 +04:00
uecho "$scriptname: renommer un fichier ou les fichiers d'un répertoire
2013-08-27 15:14:44 +04:00
USAGE
$scriptname -f FILE [cmds...]
$scriptname FILE [cmds...]
2014-10-12 22:54:49 +04:00
Une ou plusieurs commandes peuvent être spécifiées, séparées //
La commande par défaut est 'fixcase'
2013-08-27 15:14:44 +04:00
OPTIONS
2014-10-12 22:54:49 +04:00
-N, --detect-always
Pour la commande conv, ne pas optimiser le calcul de l'encoding. Cette
option n'est valide que si src_enc n'est pas spécifié. On assume que
tous les fichiers n'ont pas le même encoding: l'encoding src_enc est
donc recalculé à chaque fois.
-r, --reverse
Pour la commande conv, inverser src_enc et dest_enc, qui doivent être
tous les deux spécifiés.
-f, --file FILE
Spécifier le fichier ou le répertoire concerné par le renommage. Les
aliases -d et --dir sont aussi reconnus.
Si cette option n'est pas spécifiée, le premier argument est considéré
comme le nom du fichier ou du répertoire à renommer.
Si un répertoire est spécifié, le traitement est appliqué à tous les
fichiers et répertoires de façon récursive, sans limite de profondeur.
--show-cmd
Afficher la commande qui serait exécutée
2014-10-12 22:54:49 +04:00
COMMANDES
C, conv dest_enc [src_enc]
2014-10-12 22:54:49 +04:00
Convertir le nom du fichier dans un autre encoding.
dest_enc est l'encoding destination. Il doit être spécifié.
src_enc est l'encoding source. S'il n'est pas spécifié ou vaut 'detect',
il est autodétecté.
2014-11-06 08:06:57 +04:00
U, utf8 [src_enc]
2014-10-12 22:54:49 +04:00
Equivalent à conv utf8 src_enc
2014-11-06 08:06:57 +04:00
L, latin1 [src_enc]
2014-10-12 22:54:49 +04:00
Equivalent à conv latin1 src_enc
2014-10-22 11:43:56 +04:00
lc, latin1compat
Transformer certains caratères UTF-8 en équivalents qui existent en Latin1
2014-11-06 08:06:57 +04:00
na, noaccents
2014-10-12 22:54:49 +04:00
Transformer les caractères accentués en caractères non accentués
l, lowercase
2014-10-12 22:54:49 +04:00
Transfomer le nom en minuscule
u, uppercase
2014-10-12 22:54:49 +04:00
Transformer le nom en majuscule
f, fixcase
2019-05-18 07:44:46 +04:00
Transformer le nom en minuscule s'il est entièrement en majuscule
[sed] s/from/to/opts
Renommer le fichier avec l'expression régulière de sed 's/from/to/opts'"
2013-08-27 15:14:44 +04:00
}
2014-10-12 22:54:49 +04:00
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
}
2013-08-27 15:14:44 +04:00
2014-10-12 22:54:49 +04:00
function detect_enc() {
local filename enc
if [ -f "$1" ]; then
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 ]
}
2013-08-27 15:14:44 +04:00
2014-10-12 22:54:49 +04:00
function before_parse_cmd() {
case "$1" in
conv|c)
2014-10-12 22:54:49 +04:00
if [ -n "$OPTIMIZE_CONV" ]; then
local to="$2"
[ -n "$to" ] && setx CONV_TO=__norm_encoding "$to"
2013-08-27 15:14:44 +04:00
2014-10-12 22:54:49 +04:00
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
}
2013-08-27 15:14:44 +04:00
2014-10-12 22:54:49 +04:00
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
2013-08-27 15:14:44 +04:00
fi
2014-10-12 22:54:49 +04:00
}
2013-08-27 15:14:44 +04:00
2014-10-12 22:54:49 +04:00
function parse_cmd() {
local cmd="$1"; shift
local -a args
case "$cmd" in
2014-11-06 08:06:57 +04:00
utf8|U) parse_cmd conv utf8 "$@";;
latin1|L) parse_cmd conv latin1 "$@";;
conv|c)
2014-10-12 22:54:49 +04:00
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
;;
2014-10-22 11:43:56 +04:00
latin1compat|lc) echo _latin1compat;;
2014-11-06 08:06:57 +04:00
noaccents|na|fixchars|fc) echo _noaccents;;
2014-10-12 22:54:49 +04:00
lowercase|lower|l) echo _lowercase;;
uppercase|upper|u) echo _uppercase;;
fixcase|fix|f) echo _fixcase;;
2019-05-18 07:44:46 +04:00
s/*) qvals sed "$cmd" "$@";;
sed) qvals sed "$@";;
2014-10-12 22:54:49 +04:00
*)
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
2013-08-27 15:14:44 +04:00
eend
2014-10-12 22:54:49 +04:00
else
if [ "$newname" != "$oldname" ]; then
estep "$oldname --> $newname"
mv "$FILE" "$dir/$newname" || die
FILE="$dir/$newname"
fi
2013-08-27 15:14:44 +04:00
fi
}
2014-10-12 22:54:49 +04:00
CONV_FROM=
CONV_TO=
2014-11-06 08:06:57 +04:00
OPTIMIZE_CONV=1
REVERSE_CONV=
FILE=
show_cmd=
2014-10-12 22:54:49 +04:00
parse_opts "${PRETTYOPTS[@]}" \
--help '$exit_with display_help' \
-N,--detect-always OPTIMIZE_CONV= \
-r,--reverse REVERSE_CONV=1 \
-f:,--file:,-d:,--dir: FILE= \
2014-11-06 08:06:57 +04:00
--show-cmd show_cmd=1 \
2014-10-12 22:54:49 +04:00
@ args -- "$@" && set -- "${args[@]}" || die "$args"
if [ -z "$FILE" ]; then
FILE="${1:--}"
shift
fi
2014-10-12 22:54:49 +04:00
[ "$FILE" == - ] && FILE=/dev/stdin
if [ "$FILE" != /dev/stdin ]; then
[ -e "$FILE" ] || die "$FILE: fichier introuvable"
fi
[ $# -gt 0 ] || set -- fixcase # commande par défaut
2014-10-12 22:55:37 +04:00
CMD= # la commande finale à lancer pour convertir le nom du fichier
2014-10-12 22:54:49 +04:00
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
2013-08-27 15:14:44 +04:00
done
2014-10-12 22:54:49 +04:00
2014-11-06 08:06:57 +04:00
if [ -n "$show_cmd" ]; then
echo "$CMD"
elif [ "$FILE" == /dev/stdin ]; then
2014-10-12 22:54:49 +04:00
eval "$CMD"
elif [ -f "$FILE" -o -d "$FILE" ]; then
fnconv
else
die "$FILE: fichier invalide"
fi