Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#1 Le 19/01/2016, à 14: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 :

mini_203391sed.png

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, à 15:14)

#2 Le 19/01/2016, à 16: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, à 16:38)


Arbiel Perlacremaz
LDLC Aurore NK3S-8-S4 Ubuntu 20.04
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, à 17: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 wink )

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, à 17:51)

#4 Le 20/01/2016, à 08: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.


Archlinux sur Xiaomi Air 13

Hors ligne

#5 Le 20/01/2016, à 11:09

Compte anonymisé

Re : [Script] générateur de substitution SED

Merci,

tu me dira ce que tu en penses wink