241 lines
		
	
	
		
			6.6 KiB
		
	
	
	
		
			Bash
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			241 lines
		
	
	
		
			6.6 KiB
		
	
	
	
		
			Bash
		
	
	
		
			Executable File
		
	
	
	
	
#!/bin/bash
 | 
						|
# -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8
 | 
						|
source "$(dirname "$0")/lib/ulib/ulib" || exit 1
 | 
						|
urequire DEFAULTS
 | 
						|
 | 
						|
function display_help() {
 | 
						|
    uecho "$scriptname: renommer un fichier ou les fichiers d'un répertoire
 | 
						|
 | 
						|
USAGE
 | 
						|
    $scriptname [options] <file|dir> [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.
 | 
						|
 | 
						|
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é.
 | 
						|
    utf8 [src_enc]
 | 
						|
        Equivalent à conv utf8 src_enc
 | 
						|
    latin1 [src_enc]
 | 
						|
        Equivalent à conv latin1 src_enc
 | 
						|
    lc, latin1compat
 | 
						|
        Transformer certains caratères UTF-8 en équivalents qui existent en Latin1
 | 
						|
    n, 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"
 | 
						|
}
 | 
						|
 | 
						|
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) parse_cmd conv utf8 "$@";;
 | 
						|
    latin1) 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|noa|n|fixchars) echo _noaccents;;
 | 
						|
    lowercase|lower|l) echo _lowercase;;
 | 
						|
    uppercase|upper|u) echo _uppercase;;
 | 
						|
    fixcase|fix|f) 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 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 [ "$FILE" == /dev/stdin ]; then
 | 
						|
    eval "$CMD"
 | 
						|
elif [ -f "$FILE" -o -d "$FILE" ]; then
 | 
						|
    fnconv
 | 
						|
else
 | 
						|
    die "$FILE: fichier invalide"
 | 
						|
fi
 |