AWK/SED pour editer/supprimer dans un fichier

Bonjour :smiley:

J’ai un fichier constitué d’adresse email (Alias pour Postfix) et je voudrais le gérer simplement (ajouter/modifier/supprimer) via un script Bash.

Exemple d’un fichier alias

user@domaine.local user@yahoo.fr userb@wanadoo.fr
moi@domaine2.local moi@monfai.net user@domaine.local
etc...

Je voudrais par exemple rajouter l’alias "userx@fai.org" pour “user@domaine.local” mais je ne sais pas trop comment faire, car pour compliquer la chose l’utilisateur “moi@domaine2.local” à aussi un alias pointant sur “user@domaine.local” :doh:

Je voudrais aussi pouvoir enlever l’alias "user@yahoo.fr" de “user@domaine.local”.

Sachant que dans mon fichier la première adresse (user@domaine.local,moi@domaine2.local,etc…) est toujours unique mais par contre peut se trouver aussi en tant qu’Alias sur une adresse… :083

AWK/SED ne me donne pas de bon résultat, en gros je casse mon fichier :075

Au secours merci :smiley:

sed "s/^\(user@domaine\.local\)/\1 userx@fai.org/" nom_de_ton_fichier_d_alias

si tu vois que ça marche, tu finalises par :

sed -i~ "s/^\(user@domaine\.local\)/\1 userx@fai.org/" nom_de_ton_fichier_d_alias

pour :

tu peux essayer :

sed "s/^\(user@domaine\.local.*\)\( user@yahoo\.fr\)\(.*$\)/\1\3/" nom_de_ton_fichier_d_alias

Peut-être que ça ne marchera pas si l’email est le dernier du domaine en question, pas testé ce cas (à toi de bosser quand même !)

Edit: apparemment ça ne marche pas si email en fin de ligne. Cherche un peu, j’ai pas trop le temps
Edit 2 :Si ça marche en fait même si email en fin de ligne, liquide vaisselle ?

Pareil, si ça marche tu finalise avec -i~, évidement sudo si nécessaire …

Depuis le temps que je l’avais initié :

[code]#!/bin/bash

nomScript="${0##*/}"
function gestHelp
{
e=$1
shift
cat >&2 <<HELP
$@
Usage : ${nomScript} -f fichier [-c|-s email [-a alias[,…]]| -m email -a old -n new]
-f : fichier à traiter
-c, -s : Création ou suppression d’une adresse mail.
Si l’option -a est utilisée avec l’instruction -c, les alias sont ajoutés. L’adresse mail est créée si inexistante.
Si l’option -a est utilisée avec l’instruction -s, seuls les alias spécifiés sont supprimés.
-m : l’alias est remplacé par pour l’adresse email donnée.
HELP
exit $e
}

function erreur
{
e=$1
shift
echo >&2 "Erreur : $@"
exit $e
}

function action_c
{
trouve=false
while read
do
set – ${REPLY}
email=$1
shift
if [[ ${email} == ${_email} ]]
then
trouve=true
for unAlias in "${_alias[@]}"
do
[[ $@ == ${unAlias} ]] || set – $@ ${unAlias}
done
echo "${_email} " "$@"
else
echo "${REPLY}"
fi
done

${trouve} || echo "${_email} " ${_alias[@]}
:

}

function action_m
{
while read
do
set – ${REPLY}
email=$1
shift
if [[ ${email} == ${_email} ]] && [[ $@ != ${_nalias} ]]
then
infos=( $@ )
for idx in ${!infos[@]}
do
[[ ${infos[idx]} == ${_alias} ]] && infos[idx]=${_nalias}
done
echo "${_email} " ${infos[@]}
else
echo "${REPLY}"
fi
done
:
}

function action_s
{
while read
do
set – ${REPLY}
email=$1
shift
if [[ ${email} == ${_email} ]]
then
sesAlias=
[[ ${_alias[@]} ]] && for ele
do
[[ ${_alias[@]} == ${ele} ]] || sesAlias+=( ${ele} )
done
[[ ${sesAlias[@]} ]] && echo "${email} " ${sesAlias[@]}
else
echo "${REPLY}"
fi
done
:
}

tmpFile="${TMPDIR:-/tmp}/$$${nomScript}"

_email=
_alias=
_nalias=
_fichier=
_action=
while getopts :f:c:m:s:a:n: option
do
case $option in
"?") gestHelp 1 “Option non valide : -${OPTARG}”;;
":") gestHelp 1 “Argument manquant pour l’option -${OPTARG}”;;
f) _fichier="${OPTARG}";;
c|s|m) _action+=${option}
_email=${OPTARG};;
a) _alias=( ${OPTARG//,/ } );;
n) _nalias="${OPTARG}";;
esac
done

[[ ${_fichier} ]] || gestHelp 2 “Je ne sais pas dans quel fichier écrire !”

[[ -f “${_fichier}” ]] || gestHelp 2 "Fichier non trouvé : " “${_fichier}”

[[ ${_action} ]] || gestHelp 2 “Je ne sais pas quelle action réaliser !”

[[ ${#_action} == 1 ]] || gestHelp 2 “Je ne sais pas traiter plusieurs actions en même temps !”

[[ ${_action} = m ]] && {
(( ${#_alias[@]} == 0 )) && gestHelp 2 “Quel alias dois-je modifier ?”
(( ${#_alias[@]} > 1 )) && gestHelp 2 “Je ne sais modifier qu’un seul alias à la fois !”
[[ ${_nalias} ]] || gestHelp 2 “Dois-je deviner la nouvelle valeur de l’alias ?”
}

touch “${_tmpFile}” &>/dev/null || erreur 3 “Impossible de créer le fichier temporaire.”

(
shopt -s nocasematch
rm "${_tmpFile}"
exec > “${_tmpFile}” < "${fichier}"
eval action
${_action}
) && [ -f “${_tmpFile}” ] && mv “${_tmpFile}” “${_fichier}”[/code]

note : je n’ai volontairement pas mis de commentaire ni utilisé sed/awk …

Pourquoi ne pas simplement utiliser :
[code]mktemp "XXX_${nomScript}"[/code]
ou
[code]mktemp --tmpdir="${TMPDIR:-/tmp}" "XXX_${nomScript}"[/code]
Sinon j'aime bien ton script.

Pourquoi ne pas simplement utiliser :

ou

Sinon j’aime bien ton script.

pourquoi pas mktemp ?
En fait, je préfère utiliser le pid du process comme partie dynamique du fichier. Cela me permet d’associer le fichier temporaire au processus si le script est lancé plusieurs fois (je ne parle pas forcément de ce script, mais en règle générale). Alors certes, on peut valoriser le template avec le pid mais dans ce cas le mécanisme de mktemp n’a plus d’intérêt.

Sinon merci !

[quote=“Totor”]pourquoi pas mktemp ?
En fait, je préfère utiliser le pid du process comme partie dynamique du fichier. Cela me permet d’associer le fichier temporaire au processus si le script est lancé plusieurs fois (je ne parle pas forcément de ce script, mais en règle générale). Alors certes, on peut valoriser le template avec le pid mais dans ce cas le mécanisme de mktemp n’a plus d’intérêt.[/quote]
Il en garde toujours car tu as la garanti que ton fichier est unique (en fait en C il effectue un open avec l’option O_EXCL ce qui assure que c’est lui qui vient de le créer et pas quelqu’un d’autre, probablement via la fonction mktemp du C).

La probabilité de collision est faible, pas inexistante :slightly_smiling:

oui, je vois la nuance …
je n’y voyais que l’intérêt de l’unicité mais pas de la propriété (au sens appartenance)