1
votes

Supprimer les lignes du fichier entre la correspondance de motif

Comment supprimer toutes les lignes entre deux modèles dans un fichier à l'aide de .

Ici, le modèle est // test et // endtest , contenu du fichier:

blah blah blah
c
f
f
[
]
//test
//endtest
l
dsf
dsfs

Résultat attendu:

blah blah blah
c
f
f
[
]
//test
all text to be deleted 
line1
line2
xyz
amv
{
//endtest
l
dsf
dsfs


3 commentaires

voir aussi Comment sélectionner des lignes entre deux motifs?


Si awk est une alternative viable pour vous, vous devriez vérifier cette réponse que j'ai écrite il y a quelque temps: stackoverflow.com/ a / 31112076/42580


N'utilisez pas d'expressions de plage car elles rendent les tâches triviales très légèrement plus brèves, mais nécessitent une réécriture complète ou du code en double lorsque vos exigences changent le moins du monde (par exemple pour tester une valeur à l'intérieur de la plage ou inclure / exclure les lignes de début / fin de plage) . Utilisez plutôt une variable d'indicateur. Étant donné que sed n'a pas de variables, vous ne devriez pas utiliser sed pour des tâches comme celle-ci, utilisez simplement awk à la place, voir par exemple stackoverflow. com / a / 55721516/1745001 .


3 Réponses :


2
votes

Avec awk:

$ awk '/\/\/endtest/{p=0} !p; /\/\/test/{p = 1}' file
blah blah blah
c
f
f
[
]
//test
//endtest
l
dsf
dsfs


5 commentaires

Vous devez supprimer votre réponse car il est clairement écrit que la solution doit être résolue avec sed. Ou?


@YesThatIsMyName non, la question a été modifiée après avoir répondu


Ensuite, vous recevrez 1UP de ma part :-D


Les gens @YesThatIsMyName publient souvent des questions demandant une réponse dans un outil spécifique simplement parce qu'ils ne savent pas mieux. Restreindre les réponses uniquement à l'outil qu'ils ont demandé (à moins qu'ils ne soient très précis qu'ils ne peuvent utiliser que cet outil) alors qu'il existe une meilleure solution utilisant un autre outil n'est pas utile. Dans ce cas, sed et awk sont tous deux des outils standard qui existent dans chaque installation UNIX et les gens se demandent souvent lequel d'entre eux utiliser pour quelle tâche, il est donc très courant que les gens demandent une solution en 1 et acceptent une solution dans l'autre. .


@EdMorton Merci pour l'explication détaillée.



3
votes

C'est une caractéristique commune de sed
sed -E '/^\/\/test$/,/^\/\/endtest/{/^\/\/(end)?test$/!d;}'

Comme / est utilisé pour lier des regex, ils doivent être échappés, dans regex .

Si vous souhaitez conserver des marques (comme demandé):

sed '/^\/\/test$/,/^\/\/endtest/{/^\/\/\(end\)\{0,1\}test$/!d;}'

Explication:

Jetez un œil à info sed , recherchez sed address -> Regexp Addresses et Adresses de plage .

Entouré de {...} , le symbole // signifie n'importe quelle limite. P >

L'expression régulière vide '//' répète le dernier régulier correspondance d'expression (il en va de même si l'expression régulière vide est passé à la commande 's').

! signifie pas , puis d pour supprimer la ligne

Alternative: Vous pouvez écrire:

sed -E '/^\/\/(end)?test$/,//{//!d}'

ou

sed '/^\/\/\(end\)\?test$/,//{//!d}' 

Fonctionnera de la même manière, mais attention, cela pourrait inverser l'effet si un motif supplémentaire // endtest peut exister avant premier motif ouvert ( // test ).

... Tout cela a été fait, en utilisant GNU sed 4.4 !

Sous MacOS, BSD sed

Sous MacOS, j'ai supprimé avec succès les lignes recherchées avec cette syntaxe:

sed '/^\/\/test$/,/^\/\/endtest/{//!d}'

2 commentaires

obtenir l'erreur ci-dessous stackoverflow.com/users/1765658/f-hauri sed '/ ^ \ / \ / test $ /, / ^ \ / \ / endtest / {//! d} 'test.txt sed: mauvaise expression régulière' ': (sous) expression vide


Quelle version de sed (et OS) utilisez-vous?



0
votes

si vos données sont dans le fichier 'd', essayez gnu sed:

sed -E '/\/\/test/,/\/\/endtest/{/\/\/.*test/!d}' d


0 commentaires