it-swarm.com.de

Fügen Sie eine Zeile an einer bestimmten Zeilennummer mit sed oder awk ein

Ich habe eine Skriptdatei, die ich mit einem anderen Skript ändern muss, um einen Text in der 8. Zeile einzufügen.

Einzufügende Zeichenfolge: Project_Name=sowstest in eine Datei namens start.

Ich habe versucht, awk und sed zu verwenden, aber mein Befehl wird unleserlich.

129
ashok
sed -i '8i8 This is Line 8' FILE

fügt in Zeile 8 ein

8 This is Line 8

in Datei DATEI

-i nimmt die Änderung direkt an der Datei FILE vor, keine Ausgabe an stdout, wie in den Kommentaren von glenn jackman erwähnt.

207
user unknown

Eine ed Antwort

ed file << END
8i
Project_Name=sowstest
.
w
q
END

. in einer eigenen Zeile beendet den Eingabemodus; w schreibt; q wird beendet. GNU ed hat einen wq Befehl zum Speichern und Beenden, aber alte Eds nicht.

Weitere Informationen: https://gnu.org/software/ed/manual/ed_manual.html

27
glenn jackman

Für POSIX sed (und zum Beispiel für OS X sed, das unten stehende sed) muss nach i ein Backslash und eine Newline folgen. Mindestens in OS X 'sed ist nach dem eingefügten Text kein Zeilenumbruch enthalten:

$ seq 3|gsed '2i1.5'
1
1.5
2
3
$ seq 3|sed '2i1.5'
sed: 1: "2i1.5": command i expects \ followed by text
$ seq 3|sed $'2i\\\n1.5'
1
1.52
3
$ seq 3|sed $'2i\\\n1.5\n'
1
1.5
2
3

Um eine Zeile zu ersetzen, können Sie die Befehle c (ändern) oder s (ersetzen) mit einer numerischen Adresse verwenden:

$ seq 3|sed $'2c\\\n1.5\n'
1
1.5
3
$ seq 3|gsed '2c1.5'
1
1.5
3
$ seq 3|sed '2s/.*/1.5/'
1
1.5
3

Alternativen mit awk:

$ seq 3|awk 'NR==2{print 1.5}1'
1
1.5
2
3
$ seq 3|awk '{print NR==2?1.5:$0}'
1
1.5
3

awk interpretiert umgekehrte Schrägstriche in Variablen, die mit -v übergeben wurden, jedoch nicht in Variablen, die mit ENVIRON übergeben wurden:

$ seq 3|awk -v v='a\ba' '{print NR==2?v:$0}'
1
a
3
$ seq 3|v='a\ba' awk '{print NR==2?ENVIRON["v"]:$0}'
1
a\ba
3

Sowohl ENVIRON als auch -v Werden von POSIX definiert.

15
Lri

die awk antwort

awk -v n=8 -v s="Project_Name=sowstest" 'NR == n {print s} {print}' file > file.new
15
glenn jackman

OS X/macOS sed

Das -i flag funktioniert unter macOS sed anders als in GNU sed.

So verwenden Sie es unter macOS/OS X:

sed -i '' '8i\
8 This is Line 8' FILE

Sehen man 1 sed Für mehr Information.

13

Perl-Lösungen:

schnell und dreckig:

Perl -lpe 'print "Project_Name=sowstest" if $. == 8' file

  • -l Entfernt Zeilenumbrüche und fügt sie wieder hinzu, so dass "\ n" nicht mehr erforderlich ist
  • -p Durchläuft die Eingabedatei und druckt jede Zeile
  • -e Führt den Code in einfachen Anführungszeichen aus

$. Ist die Zeilennummer

entspricht der awk-Lösung von @ glenn unter Verwendung der folgenden Argumente:

Perl -slpe 'print $s if $. == $n' -- -n=8 -s="Project_Name=sowstest" file

  • -s Aktiviert einen rudimentären Argument-Parser
  • -- Verhindert, dass -n und -s vom standardmäßigen Perl-Argument-Parser analysiert werden

argumente für Positionsbefehle:

Perl -lpe 'BEGIN{$n=shift; $s=shift}; print $s if $. == $n' 8 "Project_Name=sowstest" file

umgebungsvariablen:

setenv n 8 ; setenv s "Project_Name=sowstest"
echo $n ; echo $s
Perl -slpe 'print $ENV{s} if $. == $ENV{n}' file

ENV ist der Hash, der alle Umgebungsvariablen enthält

Getopt zum Parsen von Argumenten in Hash% o:

Perl -MGetopt::Std -lpe 'BEGIN{getopt("ns",\%o)}; print $o{s} if $. == $o{n}' -- -n 8 -s "Project_Name=sowstest" file

Getopt :: Lange und längere Optionsnamen

Perl -MGetopt::Long -lpe 'BEGIN{GetOptions(\%o,"line=i","string=s")}; print $o{string} if $. == $o{line}' -- --line 8 --string "Project_Name=sowstest" file

Getopt ist die empfohlene Standardbibliothekslösung.
Dies mag für einzeilige Perl-Skripte übertrieben sein, kann aber durchgeführt werden

6
Chris Koknat

sed -e '8iProject_Name=sowstest' -i start using GNU sed

Probelauf:

[[email protected] ~]# for ((i=1; i<=10; i++)); do echo "Line #$i"; done > a_file
[[email protected] ~]# cat a_file
Line #1
Line #2
Line #3
Line #4
Line #5
Line #6
Line #7
Line #8
Line #9
Line #10
[[email protected] ~]# sed -e '3ixxx inserted line xxx' -i a_file 
[[email protected] ~]# cat -An a_file 
     1  Line #1$
     2  Line #2$
     3  xxx inserted line xxx$
     4  Line #3$
     5  Line #4$
     6  Line #5$
     7  Line #6$
     8  Line #7$
     9  Line #8$
    10  Line #9$
    11  Line #10$
[[email protected] ~]# 
[[email protected] ~]# sed -e '5ixxx (inserted) "line" xxx' -i a_file
[[email protected] ~]# cat -n a_file 
     1  Line #1
     2  Line #2
     3  xxx inserted line xxx
     4  Line #3
     5  xxx (inserted) "line" xxx
     6  Line #4
     7  Line #5
     8  Line #6
     9  Line #7
    10  Line #8
    11  Line #9
    12  Line #10
[[email protected] ~]# 
5
jno

Für diejenigen, die unter SunOS arbeiten, das nicht GNU ist, hilft der folgende Code:

sed '1i\^J
line to add' test.dat > tmp.dat
  • ^ J wird mit ^ V + ^ J eingefügt
  • Fügen Sie nach '1i die neue Zeile ein.
  • \ MUSS das letzte Zeichen der Zeile sein.
  • Der zweite Teil des Befehls muss in einer zweiten Zeile stehen.
5
Nasri Najib