#1 Le 19/01/2016, à 13:00
- Compte anonymisé
[Script] générateur de substitution SED
Bonjour,
on voit souvent sur le forum des commandes basés sur sed qui font tel ou tel substitution. Malheureusement la syntaxe n'est pas forcément évident à comprendre alors je me suis un petit script qui me permet de faire une embauche d'une ligne de commande.
Peut-être utile pour n'importe qui souhaite faire une substitution dans un fichier. (demande yad)
#/bin/bash
#[[:alnum:]] [[:alpha:]] [[:blank:]](space or tab) [[:cntrl:]] [[:digit:]] [[:graph:]] [[:lower:]] [[:print:]] (inverse de cntrl) [[:punct:]] [[:space:]] [[:upper:]] [[:xdigit:]]
exemple=",.*,\^$,\^.*$,\^[[:blank:]]*$,\^#.*$,[[:lower:]],[[:upper:]]"
exemple2=",(&),\\\U&,\\\L&"
exemple3=",/etc/apt/sources.list,/var/log/Xorg.0.log,*,\"\$\@\",\"\$1\""
exemple4=",test.txt,/dev/stdout,/dev/stderr"
defaut="substitution,affichage,effacement,renommer fichier(s) (substitution),ajouter une ligne vide une ligne sur deux"
quelx()
{
X=$(yad --text "Ligne X" --entry)
}
quely()
{
Y=$(yad --text "Ligne Y" --entry)
}
menu()
{
type=""
traite=""
invers=""
motif1=""
motif2=""
submotif1=""
submotif2=""
subsepar=""
occu=""
test=$(yad --witdh=1000 --title="" --form --item-separator="," --title "Sed/rename generator" \
--text="^a lignes commençant par a, a$ lignes finissant par a, . un caractère, a* un ou plusieurs a, [abc] a ou b ou c, [a-z] a à z, éperluette renvoi motif 1. Pour utiliser un point ,écrire antislash-point" \
--field="type":CBE \
--field="sélection":CBE \
--field="sélection inverser la sélection":CBE \
--field="sélection motif 1":CBE \
--field="sélection motif 2":CBE \
--field="substitution motif 1 (recherche)":CBE \
--field="substitution motif 2 (remplace par)":CBE \
--field="substitution séparateur de champ":CBE \
--field="substitution occurences":CBE \
--field="substitution sensibilité de la case":CBE \
--field="fichier(s) à traiter":CBE \
--field="fichier de destination":CBE \
--field="substitutions/effacement supplémentaire ?":CBE \
"$defaut" \
"toutes,la Xième,la dernière,entre la X et la Y,si contient motif 1,entre motif 1 et motif 2,entre la X et le motif 1,entre le motif 1 et la X,entre la X et la dernière,la Xième et les Y suivantes,la Xième et saute Y lignes puis re-efface (jusqu'a la fin)" \
"non,oui" "$exemple" "$exemple" "$exemple" "$exemple2" "/,:" "toutes,1ère,la Xième" "oui,non" "$file1$exemple3" "$file2$exemple4" "non,oui")
type="$(echo $test|cut -d "|" -f 1)"
traite="$(echo $test|cut -d "|" -f 2)"
invers="$(echo $test|cut -d "|" -f 3)"
motif1="/$(echo $test|cut -d "|" -f 4)/"
motif2="/$(echo $test|cut -d "|" -f 5)/"
submotif1="$(echo $test|cut -d "|" -f 6)"
submotif2="$(echo $test|cut -d "|" -f 7)"
subsepar="$(echo $test|cut -d "|" -f 8)"
occur="$(echo $test|cut -d "|" -f 9)"
file1="$(echo $test|cut -d "|" -f 11)"
file2="$(echo $test|cut -d "|" -f 12)"
sedseparator="'"
[ -z "$file2" ]||filedest=" > $file2"
case "$traite" in
"toutes")
selec=""
[ "$submotif1" == "" ]&&[ "$invers" == "non" ]&&([ "$type" == "affichage" ]||[ "$type" == "effacement" ]||[ "$type" == "ajouter une ligne vide une ligne sur deux" ])&&sedseparator=""
;;
"la Xième")
quelx
selec="$X"
[ "$submotif1" == "" ]&&[ "$invers" == "non" ]&&([ "$type" == "affichage" ]||[ "$type" == "effacement" ]||[ "$type" == "ajouter une ligne vide une ligne sur deux" ])&&sedseparator=""
;;
"la dernière")
selec="$"
;;
"entre la X et la Y")
# X doit être plus petit que Y
quelx
quely
selec="$X,$Y"
;;
"si contient motif 1")
selec="$motif1"
;;
"entre motif 1 et motif 2")
selec="$motif1,$motif2"
;;
"entre la X et le motif 1")
quelx
selec="$X,$motif1"
;;
"entre le motif 1 et la X")
quelx
selec="$motif1,$X"
;;
"entre la X et la dernière")
quelx
selec="$X,$"
;;
"la Xième et les Y suivantes")
quelx
quely
selec="$X,+$Y"
;;
"la Xième et saute Y lignes puis re-efface (jusqu'a la fin)")
quelx
quely
selec="$X~$Y"
;;
*)
;;
esac
case "$occur" in
"1ère")
occu=""
;;
"toutes")
occu="g"
;;
"la Xième")
X=$(yad --text "quel occurence ?" --entry)
occu="$X"
;;
*)
;;
esac
case "$(echo $test|cut -d "|" -f 10)" in
"oui")
case=""
;;
"non")
case="i"
;;
*)
;;
esac
[ "$invers" == "non" ]||inver="!"
[ "$traite" == "toutes" ]||patt="p"
}
menu
case "$(echo $test|cut -d "|" -f 13)" in
"non")
;;
"oui")
e="-e "
;;
*)
;;
esac
case "$type" in
"substitution")
[ "$submotif1" == "" ]&&echo "Erreur : Pas de motif à substituer, ça risque de ne pas marcher"
multi=" $e$sedseparator$selec${inver}s$subsepar$submotif1$subsepar$submotif2$subsepar$occu$case$sedseparator"
while [ "$(echo $test|cut -d "|" -f 13)" == "oui" ]
do
menu
multi="${multi} $e$sedseparator$selec${inver}s$subsepar$submotif1$subsepar$submotif2$subsepar$occu$case$sedseparator"
done
echo "sed$multi $file1$filedest"
;;
"effacement")
multi=" $e$sedseparator$selec${inver}d$sedseparator"
while [ "$(echo $test|cut -d "|" -f 13)" == "oui" ]
do
defaut="effacement,substitution,affichage,renommer fichier(s) (substitution),ajouter une ligne vide une ligne sur deux"
menu
multi="${multi} $e$sedseparator$selec${inver}d$sedseparator"
done
echo "sed$multi $file1$filedest"
;;
"affichage")
[ "$submotif1" == "" ]&&echo "sed -n $sedseparator$selec${inver}p$sedseparator $file1$filedest"||echo "sed -n $sedseparator${selec}${inver}s${subsepar}$submotif1$subsepar$submotif2$subsepar$occu${case}$patt$sedseparator $file1$filedest"
;;
"renommer fichier(s) (substitution)")
[ "$submotif1" == "" ]&&echo "Erreur : Pas de motif à substituer, ça risque de ne pas marcher"
echo "rename $sedseparator$selec${inver}s/$submotif1/$submotif2/$occu$case$sedseparator $file1"
;;
"ajouter une ligne vide une ligne sur deux")
echo "sed $sedseparator${selec}${inver}G$sedseparator $file1$filedest"
;;
*)
;;
esac
aperçu et quelques explications :
EDIT : correction et optimisation
EDIT : ajout de "ajouter une ligne vide une ligne sur deux" et "si ne contient pas motif 1" et j'ai rajouté du texte comment utiliser un point.
EDIT : simplification, modification des noms des champs
EDIT : ajoute de "sélection ligne 1", "sélection ligne 2", "choix substitution"
Dernière modification par Compte anonymisé (Le 20/01/2016, à 14:14)
#2 Le 19/01/2016, à 15:34
- Arbiel
Re : [Script] générateur de substitution SED
Bonjour
Edit : je n'avais pas vu que le fichier à modifier est facultatif, et que lorsqu'il n'est pas renseigné, la commande est affichée sur /dev/stdout ;
Ne te méprends pas sur le sens des remarques ci-dessous qui ne visent nullement à dénigrer ton travail que je trouve fort intéressant et utile. La syntaxe de sed est effectivement très absconse et disposer d'un script comme le tien va permettre à beaucoup d'entre nous de ne plus perdre leur temps à mettre au point l'opération qu'ils veulent réaliser.
1) il peut y avoir confusion dans la tête de l'utilisateur entre "motif 1" et "motif 2" qui servent à délimiter les lignes sur lesquelles porte la substitution et "motif 1" et "motif 2" qui définissent la substitution à effectuer ; pourquoi ne pas les différencier soit par "motif 3/4", soit, à mon humble avis, mieux, par un terme différent (marqueur, "à supprimer". "à insérer, …) ;
2) je ne suis pas aller au bout du script pour la raison exprimée en 3, et je me demande si le fait de laisser ce deuxième "motif 2" vide signifie bien "suppression" du "motif 1" correspondant ;
3) yad permet de naviguer dans les fichiers, ce qui est plus simple que de devoir renseigner le chemin complet du fichier ou des fichiers à traiter ; le fait de laisser vide le fichier de destination signifie-t-il que le résultat de la substitution vient remplacer le ou les fichiers à traiter ? ;
4) pour utilisation dans un script, ton script peut-il se limiter à afficher sur /dev/stdout la commande sed à utiliser ?
Et merci pour ce travail
Arbiel
Dernière modification par Arbiel (Le 19/01/2016, à 15:38)
Arbiel Perlacremaz
LDLC Aurore NK3S-8-S4 Ubuntu 20.04, GNOME 3.36.8
24.04 en cours de tests
Abandon d'azerty au profit de bépo, de google au profit de Lilo et de la messagerie électronique violable au profit de Protonmail, une messagerie chiffrée de poste de travail à poste de travail.
Hors ligne
#3 Le 19/01/2016, à 16:42
- Compte anonymisé
Re : [Script] générateur de substitution SED
Bonjour,
j'avais 2 objectifs,
- essayer de comprendre sed, dont ma connaissance était limité.
- pourvoir éventuellement fournir de l'aide sur le forum sur une question de substitution de texte (bon on a déjà des experts pour ça )
1) effectivement sur les termes on peut modifier, j'ai aussi hésité entre tel ou tel terme.
motif 1 et motif 2, c'est par rapport au menu juste au-dessus, on peut choisir les lignes à sélectionner. Motif 2 ne sera utilisé que dans un des cas : "entre motif 1 et motif 2".
je suis preneur de tout modification constructive pour les termes.
3) le script en lui-même fait rien il renvoie dans le terminal la commande à exécuter. (et il y a des X et Y à modifier dans certains cas)
4) oui, il ne fait que ça.
Dernière modification par Compte anonymisé (Le 19/01/2016, à 16:51)
#4 Le 20/01/2016, à 07:22
- k3c
Re : [Script] générateur de substitution SED
Merci Anonyme68 pour ton travail, je connais un peu awk, et je ne me suis jamais mis à sed, ça va être l'occasion.
Debian 12 sur Thinkpad reconditionné
Hors ligne
#5 Le 20/01/2016, à 10:09
- Compte anonymisé
Re : [Script] générateur de substitution SED
Merci,
tu me dira ce que tu en penses