2
votes

Avec sed ou awk, déplacez le motif de correspondance de ligne au bas du fichier

J'ai un problème similaire. J'ai besoin de déplacer une ligne dans / etc / sudoers à la fin du fichier.

La ligne que je veux déplacer:

#creates variable value
templine=$(cat /etc/sudoers | grep "#includedir /etc/sudoers.d")

#delete value
sed '/"${templine}"/d' /etc/sudoers

#write value to the bottom of the file
cat ${templine} >> /etc/sudoers

J'ai essayé avec une variable

#includedir /etc/sudoers.d

Je n'obtiens aucune erreur ni le résultat que je recherche.

Des suggestions?


1 commentaires

Que faire si #includedir /etc/sudoers.d n'existe pas dans le fichier?


4 Réponses :


2
votes

Avec awk:

$ cat test.txt
hi
this
is
#includedir /etc/sudoers.d
a
test
$ awk '$0=="#includedir /etc/sudoers.d"{lastline=$0;next}{print $0}END{print lastline}' test.txt
hi
this
is
a
test
#includedir /etc/sudoers.d

Cela dit:

  1. Si la ligne $ 0 est "#includedir /etc/sudoers.d" , définissez la variable lastline sur la valeur de cette ligne $ 0 et passez à la ligne suivante next .
  2. Si vous êtes toujours là, imprimez la ligne {print $ 0}
  3. Une fois que chaque ligne du fichier est traitée, imprimez ce qui se trouve dans la variable lastline .

Exemple :

awk '$0=="#includedir /etc/sudoers.d"{lastline=$0;next}{print $0}END{print lastline}' /etc/sudoers


2 commentaires

Je teste avec une copie de / etc / sudoers et j'obtiens un résultat comme si une commande ne s'est pas terminée. awk '$ 0 == "# includedir /etc/sudoers.d"{lastline=$0;next}{print $ 0} END {print lastline}` / etc / sudoers>


Mes excuses. J'ai mis à jour la réponse. J'ai mis un backtick à la place du guillemet simple. Cela a été corrigé.



1
votes

Vous pouvez tout faire avec sed :

sed -e '/#includedir .etc.sudoers.d/ { h; $p; d; }' -e '$G' /etc/sudoers


4 commentaires

Cela laisse une ligne vide où se trouvait le #includedir ; pour éviter cela, utilisez {h; d;} au lieu de x .


@BenjaminW .: bon point, et incluez $ p pour fonctionner également lorsque le motif est sur la dernière ligne


Cela peut réduire le fichier si l'expression rationnelle correspond plus d'une fois et ne déplace que la dernière correspondance.


@potong: vrai, mais étant donné le modèle qui est un trait souhaitable ici



0
votes

Si vous avez plusieurs entrées que vous souhaitez déplacer à la fin du fichier, vous pouvez effectuer les opérations suivantes:

sed -n '/regex/!{p;ba};H;:a;${x;s/.//;p}' file

ou

awk '/regex/{a[++c]=$0;next}1;END{for(i=1;i<=c;++i) print a[i]}' file


0 commentaires

1
votes

Cela pourrait fonctionner pour vous (GNU sed):

sed -n '/regexp/{h;$p;$b;:a;n;p;$!ba;x};p' file

Ceci supprime les lignes contenant une expression régulière spécifiée et les ajoute à la fin du fichier.

Pour déplacer uniquement la première ligne qui correspond à l'expression rationnelle, utilisez:

sed -n '/regexp/H;//!p;$x;$s/.//p' file

Cela utilise une boucle pour lire / imprimer le reste du fichier, puis ajouter la ligne correspondante.


0 commentaires