#!/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: modifier en masse un ensemble de valeurs numériques contigües dans un fichier USAGE $scriptname FILE FROMmin-FROMmax TO remplacer les nombres de FROMmin à FROMmax par leur valeur correspondante, sachant que FROMmin doit être remplacé par TO. On peut mentionner autant de couples (FROM, TO) que nécessaire: ils seront traités dans l'ordre $scriptname -r FROMmin-FROMmax TO FILEs... renommer les fichiers en remplaçant les nombres de FROMmin à FROMmax par leur valeur correspondante, sachant que FROMmin doit être remplacé par TO OPTIONS -n, --fake Afficher le fichier tel qu'il serait modifié au lieu de le modifier en place -r, --rename Renommer les fichiers au lieu de modifier le texte à l'intérieur du fichier. Attention, l'ordre des arguments est différent avec cette option" } function process_file() { local file from to fromb frome seds r file="$1"; shift [ -n "$file" ] || die "vous devez spécifier le fichier à modifier" seds= while [ $# -ge 2 ]; do from="$1" if [[ "$from" == *-* ]]; then let fromb="${from%-*}" let frome="${from#*-}" else let fromb="$from" let frome="$from" fi let to="$2"; shift 2 if [ "$to" -eq "$fromb" ]; then einfo "$fromb --> $to aucune modification n'est nécessaire" elif [ "$to" -lt "$fromb" ]; then einfo "$fromb-$frome --> $to-$((to+frome-fromb))" let from=fromb while [ "$from" -le "$frome" ]; do seds="$seds${seds:+; }s/$from/$to/g" let from=from+1 let to=to+1 done elif [ "$to" -gt "$fromb" ]; then einfo "$frome-$fromb --> $((to+frome-fromb))-$to" let from=frome let to=to+frome-fromb while [ "$from" -ge "$fromb" ]; do seds="$seds${seds:+; }s/$from/$to/g" let from=from-1 let to=to-1 done fi done edebug "Script sed: $seds" [ -n "$Fake" ] && args=() || args=(-i) args+=("$seds" "$file") sed "${args[@]}"; r=$? [ -z "$Fake" -a $r -eq 0 ] } Fake= rename= args=( --help '$exit_with display_help' -n,--Fake Fake=1 -r,--rename rename=1 ) parse_args "$@"; set -- "${args[@]}" if [ -n "$rename" ]; then from="$1"; to="$2"; shift 2 froms=("$@") ac_set_tmpfile tmptos echo "tos=(" >>"$tmptos" for file in "${froms[@]}"; do qval "$file" >>"$tmptos" done echo ")" >>"$tmptos" Fake= process_file "$tmptos" "$from" "$to" eval "$(<"$tmptos")" i=0 count=${#froms[*]} while [ $i -lt $count ]; do from="${froms[$i]}" to="${tos[$i]}" if [ "$to" == "$from" ]; then ewarn "$from: renommage non nécessaire" else estep "$from --> $to" [ -z "$Fake" ] && mv "$from" "$to" fi let i=i+1 done else process_file "$@" fi