#!/bin/bash # -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8 source "$(dirname -- "$0")/lib/ulib/auto" || exit 1 function display_help() { uecho "$scriptname: renommer un fichier ou les fichiers d'un répertoire USAGE $scriptname -f FILE [cmds...] $scriptname FILE [cmds...] Une ou plusieurs commandes peuvent être spécifiées, séparées // La commande par défaut est 'fixcase' OPTIONS -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 COMMANDES C, conv dest_enc [src_enc] 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é. U, utf8 [src_enc] Equivalent à conv utf8 src_enc L, latin1 [src_enc] Equivalent à conv latin1 src_enc lc, latin1compat Transformer certains caratères UTF-8 en équivalents qui existent en Latin1 na, noaccents Transformer les caractères accentués en caractères non accentués l, lowercase Transfomer le nom en minuscule u, uppercase Transformer le nom en majuscule f, fixcase 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'" } 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 } 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 ] } function before_parse_cmd() { case "$1" in conv|c) 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|U) parse_cmd conv utf8 "$@";; latin1|L) parse_cmd conv latin1 "$@";; conv|c) 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 ;; latin1compat|lc) echo _latin1compat;; noaccents|na|fixchars|fc) echo _noaccents;; lowercase|lower|l) echo _lowercase;; uppercase|upper|u) echo _uppercase;; fixcase|fix|f) echo _fixcase;; s/*) qvals sed "$cmd" "$@";; sed) qvals sed "$@";; *) 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 } CONV_FROM= CONV_TO= OPTIMIZE_CONV=1 REVERSE_CONV= FILE= show_cmd= parse_opts "${PRETTYOPTS[@]}" \ --help '$exit_with display_help' \ -N,--detect-always OPTIMIZE_CONV= \ -r,--reverse REVERSE_CONV=1 \ -f:,--file:,-d:,--dir: FILE= \ --show-cmd show_cmd=1 \ @ args -- "$@" && set -- "${args[@]}" || die "$args" if [ -z "$FILE" ]; then FILE="${1:--}" shift fi [ "$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 nom du fichier 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 if [ -n "$show_cmd" ]; then echo "$CMD" elif [ "$FILE" == /dev/stdin ]; then eval "$CMD" elif [ -f "$FILE" -o -d "$FILE" ]; then fnconv else die "$FILE: fichier invalide" fi