Comment puis-je écrire sur la deuxième ligne d'un fichier à partir de la ligne de commande?

29

J'ai un programme externe qui produit un fichier de sortie (large, 20K lignes possibles).

J'ai besoin d'insérer une nouvelle ligne entre la ligne existante 1 et la ligne 2. J'ai regardé awk et sed - j'utilise un liners dans chacun assez régulièrement - mais je n'ai pas été en mesure de trouver les bons commutateurs pour fais ça.

Tim Brigham
la source

Réponses:

20
awk 'NR==1{print; print "new line"} NR!=1'
Kevin
la source
12
Un peu plus court:awk 'NR==2 {print "new line"} 1'
glenn jackman
@glennjackman: votre version ne fonctionne pas sur mon système, mais la réponse fonctionne. Plus précisément, avec la vôtre, la ligne 2 est dupliquée et la nouvelle ligne est insérée entre les deux (comme la ligne 3).
Nikana Reklawyks
Existe-t-il un moyen de commencer à écrire à la 2e ligne et d'écraser toutes les lignes suivantes?
CMCDragonkai
@CMCDragonkai Je ne sais pas trop ce que vous demandez. Il suffit d'imprimer la première ligne du fichier spécifié et une deuxième ligne définie? Première ligne puis le contenu d'un fichier? La première ligne du premier fichier, puis une ligne d'un deuxième fichier pour chaque ligne restante dans le premier? Vous voudrez peut-être poser une nouvelle question avec une description très précise de ce que vous voulez, et un exemple relativement court mais complet.
Kevin
16

Pour votre cas spécifique, cela devrait être plus simple:

sed '1 { P ; x }' your-file

Explication: à la ligne 1 , procédez comme suit

  1. P Rint la ligne
  2. E x changer l'espace de motif avec l'espace de maintien (vide essentiellement le tampon)

Ensuite, la ligne (vide maintenant) est à nouveau imprimée dans le cadre du cycle.


Si vous souhaitez ajouter une nouvelle ligne au lieu d'un nouveau caractère de ligne (ce que j'ai compris au départ), utilisez simplement sedla commande de a\(ajouter):

sed '1 a\
appended line' your-file

ou même

sed '1 aappended line' your-file

Il ajoute " appended line" après la ligne 1.

angus
la source
1
sed -i '1 a\\' filepour juste une nouvelle ligne.
forcefsck
1
@forcefsck Oui, le seul inconvénient est que c'est un GNUism, comme mon deuxième '1 aapended line'exemple.
angus
8

Je suppose que l' sedapproche serait:

sed '2 i whatever_line_of_text_you_wanted_to_INSERT' filename.txt

Cela mettra le texte dans la deuxième ligne du fichier, puis la deuxième ligne réelle dans le fichier deviendra la troisième.

Notez que, en utilisant le mode d'ajout , s'il devait l'être, il devait utiliser la première ligne, car l'ajout se produira après le numéro de ligne noté.

sed '1 a whatever_line_of_text_you_wanted_to_INSERT' filename.txt

Nikhil Mulley
la source
3
sed ':a;N;$!ba;s/\n/\n\n\n/' yourBigFile

Explication.

Abhijeet Rastogi
la source
2

Cela pourrait fonctionner pour vous:

sed 1G file

Si vous souhaitez insérer somethingaprès la nouvelle ligne:

sed '1{G;s/$/something/}' file

Ou si vous avez manipulé \n:

sed '1s/$/\nsomething/' file

Bien sûr, ac'est encore plus facile:

sed '1a something' file
potong
la source
Je suis désolé, qu'est-ce que ça fait?
Nikhil Mulley
Il insère une nouvelle ligne après la ligne 1
potong
1
Ou plutôt ajoute une nouvelle ligne \nà la première ligne!
potong
1

J'utilise habituellement edpour cela:

(echo 1a; echo 'Line to insert'; echo .; echo w) | ed - filename

Semblable à une sedsolution, mais sans l'encombrement des nouvelles lignes échappées.

Arcege
la source
2
Vous pouvez épargner quelques echo« s, notamment sous bash: ed - filename <<< $'1a\nLine to insert\n.\nw'.
manatwork
1
Ne fonctionne pas dans tous les shells, par exemple dans dash, ce qui est le cas sur de nombreux systèmes /bin/sh.
Arcege
1
C'est pourquoi j'ai écrit «Vous pourriez en épargner certains echo ». Tout épargner echo s est bien » bashseule caractéristique, mais en réduisant le echonombre de 4 à 1 œuvres dans dashet kshaussi: echo '1a\nLine to insert\n.\nw' | ed - filename.
manatwork
1
Ou utilisezprintf %s\\n simplement , qui met une nouvelle ligne après chaque argument que vous lui donnez et ne bloque pas les caractères spéciaux incorporés dans la ligne que vous souhaitez insérer. Aussi, pourquoi utiliser edquand exest-il disponible?
Wildcard
1

Solution Python

python -c "import sys; lines = sys.stdin.readlines(); lines.insert(1,'New Line\n'); print ''.join(lines).strip()" < input.txt
Rahul Patil
la source
0

Utilisation des sedcodes d'échappement ANSI et (spécifiques à Bash):

# note: \ --> \\
printf '%s\n' 1 2 3 4 5 | sed -e $'1 { s/\\(.*\\)/\\1\\\ninserted line/; }'
topi
la source
0

j'utiliserais python pour cela

import fileinput

for linenum,line in enumerate(fileinput,FileInput("file",inplace=1)):
    if linenum ==1:
          print ""
          print line.rstrip() 
      else: 
          print line.rstrip()`
harish.venkat
la source
0

J'aime juste utiliser un compteur explicite:

awk '(c==1) {print "new line"} (c!=1) {print $0} {c++}' file
Professeur Awk
la source
0

La méthode la plus simple utilise printfet ex:

printf '%s\n' 1a 'my line to insert' . x | ex file

1asignifie "ajouter après la première ligne"; la .fin de l'ajout; xsignifie enregistrer et quitter.

Caractère générique
la source
0

Aucune des réponses ci-dessus ne mentionne comment enregistrer les modifications dans le fichier d'origine, ce qui est, je pense, ce que l'OP demandait.

C'est certainement ce dont j'avais besoin pour accéder à la page.

Donc, en supposant que votre fichier s'appelle output.txt

sed -i '1 a This is the second line' output.txt

Mon cas d'utilisation particulier consiste à ajouter automatiquement une déclaration de feuille de style xsl à un fichier xml junit.

sed -i '1 a <?xml-stylesheet type="text/xsl" href="junit-html.xsl"?>' junit.xml
chim
la source
yourownlinux.com/2015/04/… est la partie pertinente d'une introduction bien écrite à sed.
chim