web-dev-qa-db-fra.com

sed, insérer le fichier avant la dernière ligne

La méthode de fichier d'insertion suivante pour sed utilisé pour fonctionner, même avant la dernière ligne, mais pas plus. Est-ce un bug dans le courant sed?

Démo d'insertion de la méthode de fichier avec SED:

mkdir /tmp/test
printf '%s\n' {1..3} > /tmp/test/f1
printf '%s\n' {one,two,three,four,five,six,seven,eight,nine,ten} > /tmp/test/f2

$ cat /tmp/test/f2 | sed -e "/nine/r /tmp/test/f1" -e //N
one
two
three
four
five
six
seven
eight
1
2
3
nine
ten

$ head -9 /tmp/test/f2 | sed -e "/nine/r /tmp/test/f1" -e //N
one
two
three
four
five
six
seven
eight
nine
1
2
3

$ cat /tmp/test/f2 | sed -e "/ten/r /tmp/test/f1" -e //N
one
two
three
four
five
six
seven
eight
nine
ten
1
2
3

$ sed --version
GNU sed version 4.2.1
... 

I.e., le fichier d'insertion avant la méthode de la ligne fonctionne partout sauf la dernière ligne. Il travaillait avant. Est-ce un bug dans le courant sed?

Merci

7
xpt

Depuis que vous êtes sur gnu sed vous pouvez utiliser

'e [COMMAND]'
     This command allows one to pipe input from a Shell command into
     pattern space.

sur la la$t ligne:

sed '$e cat insert.txt' file

Avec ed (remplacer ,p avec w si vous souhaitez modifier en place):

ed -s file<<IN
- r insert.txt
,p
q
IN

ou

ed -s file <<< $'-1 r insert.txt\n,p\nq\n'

Lorsque ed lit file L'adresse actuelle est définie sur LA$t ligne. - (ou -1) Définit l'adresse actuelle sur une ligne avant (c'est-à-dire $-1) _) et r lit en insert.txt après la ligne actuelle. ,p Imprime le contenu du tampon de texte (comme j'ai dit, remplacez-le par w pour enregistrer les modifications) et q quitte l'éditeur.

5
don_crissti

Selon votre commentaire, vous "devez match contre la dernière ligne", alors je envisagerais d'utiliser le $ (dernière ligne) et i (commande insertion) dans sed. Par exemple:

sed '$ i\INSERT BEFORE LAST LINE' number.txt
1
2
3
4
INSERT BEFORE LAST LINE
5

Assurez-vous simplement que le fichier n'a pas de ligne vide comme dernière ligne et cela devrait fonctionner. Notez l'espace entre le signe du dollar et le i et la barre oblique inverse (\) après le i. Cela insérera le texte après la barre oblique inoublie à la dernière ligne sans avoir besoin d'un /pattern/ pour la dernière ligne.

Remarque: cette commande n'ajoutera qu'une ligne de texte avant la dernière ligne, pas un fichier. Si vous souhaitez insérer le contenu d'un fichier avant la dernière ligne.

Si vous souhaitez ajouter un fichier entier (et vous ne le faites pas si c'est dans sed) je voudrais utiliser ceci:

    head -n-1 first_file.txt && cat inserted_file.txt && tail -n1 first_file.txt 

Cela devrait afficher tout sauf la dernière ligne, puis cat le inserted_file.txt puis afficher la dernière ligne du first_file.txt.

6
skamazin