2010-10-21 13 views
3

Est-ce que quelqu'un sait comment remplacer line a avec line b et line b avec line a dans un fichier texte en utilisant l'éditeur sed?Comment puis-je échanger deux lignes en utilisant sed?

Je peux voir comment remplacer une ligne dans l'espace de travail avec une ligne qui est dans l'espace de maintien (c.-à-/^Paco/x ou /^Paco/g), mais si je veux prendre la ligne commençant par Paco et le remplacer par le ligne commençant par Vinh, et également prendre la ligne commençant par Vinh et le remplacer par la ligne commençant par Paco?

Supposons pour commencer qu'il ya une ligne avec Paco et une ligne avec Vinh, et que la ligne Paco se produit avant la ligne Vinh. Ensuite, nous pouvons passer au cas général.

Répondre

2
#!/bin/sed -f 
/^Paco/ { 
:notdone 
    N 
    s/^\(Paco[^\n]*\)\(\n\([^\n]*\n\)*\)\(Vinh[^\n]*\)$/\4\2\1/ 
    t 
    bnotdone 
} 

Après avoir établi/^ Paco/nous avons lu dans la mémoire tampon de modèle jusqu'à ce s // réussit (ou EOF: le tampon de motif sera imprimé inchangé). Ensuite, nous commençons à chercher/^ Paco /.

+0

Merci smilethax! Ça marche. Tu es un génie! – David

0

Un exemple simple de la GNU sed texinfo doc:

Note that on implementations other than GNU `sed' this script might 
easily overflow internal buffers. 

#!/usr/bin/sed -nf 

# reverse all lines of input, i.e. first line became last, ... 

# from the second line, the buffer (which contains all previous lines) 
# is *appended* to current line, so, the order will be reversed 
1! G 

# on the last line we're done -- print everything 
$ p 

# store everything on the buffer again 
h 
+0

Merci le sourire. Votre réponse me montre comment inverser les lignes dans un fichier, mais je voudrais juste échanger deux lignes dans le fichier. – David

+1

Vous pouvez utiliser les autres commandes telles que la branche conditionnelle (t) et les étiquettes pour le faire. Mais je préférerais Perl ou quelque chose de similaire pour ce travail. Une autre possibilité est de remplacer '\ n' par un caractère spécial avant d'utiliser sed et de tout traiter comme une longue ligne, et à la fin de remplacer les caractères (par exemple par tr). – smilingthax

+0

Si quelqu'un a un exemple de travail avec sed, ce serait le ticket. Merci. – David

0

essayer ce script awk.

s1="$1" 
s2="$2" 
awk -vs1="$s1" -vs2="$s2" ' 
{ a[++d]=$0 } 
$0~s1{ h=$0;ind=d} 
$0~s2{ 
a[ind]=$0 
for(i=1;i<d;i++){ print a[i]} 
print h 
delete a;d=0; 
} 
END{ for(i=1;i<=d;i++){ print a[i] } }' file 

sortie

$ cat file 
1 
2 
3 
4 
5 

$ bash test.sh 2 3 
1 
3 
2 
4 
5 

$ bash test.sh 1 4 
4 
2 
3 
1 
5 

Utilisez sed (ou pas du tout) pour que la substitution simple. Rien de plus compliqué, utiliser un langage de programmation

+0

Merci Ghostdog. Super script. La chose est, je suis en train d'apprendre sed, et c'est l'une des questions que je dois répondre (Ellie Quigley, Linux par exemple). Donc, si quelqu'un a un exemple de travail, ce serait génial. – David

2
cat input | tr '\n' 'ç' | sed 's/\(ç__firstline__\)\(ç__secondline__\)/\2\1/g' | tr 'ç' '\n' > output 

Remplacer __firstline__ et __secondline__ avec vos regexps souhaités. Veillez à remplacer toutes les instances de . dans votre expression rationnelle par [^ç]. Si votre texte contient effectivement ç, remplacez-le par quelque chose d'autre que votre texte n'a pas.

Questions connexes