Jak mogę zapisać do drugiej linii pliku z linii poleceń?

29

Mam zewnętrzny program, który produkuje plik wyjściowy (duże, możliwe 20 000 wierszy).

Muszę wstawić nową linię między istniejącą linią 1 i linią 2. Patrzyłem na awk i sed - Używam jednej wkładki w każdej dość regularnie - ale nie byłem w stanie wymyślić odpowiednich przełączników do Zrób to.

Tim Brigham
źródło

Odpowiedzi:

20
awk 'NR==1{print; print "new line"} NR!=1'
Kevin
źródło
12
Nieco krótszy:awk 'NR==2 {print "new line"} 1'
glenn jackman
@glennjackman: twoja wersja nie działa w moim systemie, ale odpowiedź brzmi. W szczególności, twoja linia 2 jest duplikowana, a nowa linia jest wstawiana pomiędzy oba (tak jak linia 3).
Nikana Reklawyks
Czy istnieje sposób, aby rozpocząć pisanie od drugiej linii i zastąpić wszystkie kolejne linie?
CMCDragonkai
@CMCDragonkai Nie jestem do końca pewien, o co prosisz. Wystarczy wydrukować pierwszy wiersz określonego pliku i ustawić drugi wiersz? Pierwszy wiersz, a następnie zawartość pliku? Pierwszy wiersz pierwszego pliku, a następnie wiersz z drugiego pliku dla każdej pozostałej linii w pierwszym? Możesz zadać nowe pytanie z bardzo szczegółowym opisem tego, czego chcesz, i stosunkowo krótkim, ale kompletnym przykładem.
Kevin
16

W konkretnym przypadku powinno to być prostsze:

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

Objaśnienie: w wierszu 1 wykonaj następujące czynności

  1. P rint linii
  2. E x zmień przestrzeń wzoru na przestrzeń przytrzymującą (w zasadzie opróżnia bufor)

Następnie linia (teraz pusta) jest drukowana ponownie jako część cyklu.


Jeśli chcesz dodać nową linię zamiast nowego znaku linii (co początkowo rozumiałem), po prostu użyj sedpolecenia a\(dołącz):

sed '1 a\
appended line' your-file

lub nawet

sed '1 aappended line' your-file

Dołącza „ appended line” po wierszu 1.

angus
źródło
1
sed -i '1 a\\' filetylko dla nowej linii.
forcefsck
1
@forcefsck Tak, jedyną wadą jest to, że jest to GNUism, jak mój drugi '1 aapended line'przykład.
angus
8

Myślę, że sedpodejście byłoby:

sed '2 i whatever_line_of_text_you_wanted_to_INSERT' filename.txt

Spowoduje to przeniesienie tekstu do drugiej linii pliku, a następnie faktyczna druga linia z pliku stanie się trzecią.

Zauważ, że używając trybu dołączania , jeśli musiał, musiał użyć pierwszego wiersza, ponieważ dołączanie nastąpi po zanotowanym numerze wiersza.

sed '1 a whatever_line_of_text_you_wanted_to_INSERT' filename.txt

Nikhil Mulley
źródło
3
sed ':a;N;$!ba;s/\n/\n\n\n/' yourBigFile

Wyjaśnienie.

Abhijeet Rastogi
źródło
2

To może Ci pomóc:

sed 1G file

Jeśli chcesz wstawić somethingpo nowej linii:

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

Lub jeśli sed obsługuje \n:

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

Oczywiście ajest jeszcze łatwiej:

sed '1a something' file
potong
źródło
Przepraszam, co to robi?
Nikhil Mulley,
Wstawia nowy wiersz po wierszu 1
potong
1
A raczej dodaje nowy wiersz \ndo pierwszego!
potong 30.01.12
1

Zwykle używam eddo tego:

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

Podobne do sedrozwiązania, ale bez bałaganu uciekających nowych linii.

Arcege
źródło
2
Można oszczędzić kilka echo„s, w szczególności w ramach bash: ed - filename <<< $'1a\nLine to insert\n.\nw'.
manatwork
1
Nie działa we wszystkich powłokach, na przykład w dash, która jest w wielu systemach /bin/sh.
Arcege
1
Dlatego napisałem „Możesz oszczędzić trochę echo ”. Sparing wszystko echo jest to rzeczywiście bashtylko cecha, ale zmniejszając echoliczbę od 4 do 1 w pracach dashi kshzbyt: echo '1a\nLine to insert\n.\nw' | ed - filename.
manatwork
1
Lub po prostu użyjprintf %s\\n , który umieszcza nową linię po każdym argrze, który jej podajesz i nie psuje znaków specjalnych osadzonych w linii, którą chcesz wstawić. Ponadto, edpo co korzystać, kiedy exjest dostępny?
Wildcard
1

Rozwiązanie Python

python -c "import sys; lines = sys.stdin.readlines(); lines.insert(1,'New Line\n'); print ''.join(lines).strip()" < input.txt
Rahul Patil
źródło
0

Używanie sedi (specyficzne dla Bash) kodów ucieczki ANSI:

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

użyłbym do tego Pythona

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
źródło
0

Po prostu lubię używać jawnego licznika:

awk '(c==1) {print "new line"} (c!=1) {print $0} {c++}' file
Profesor Awk
źródło
0

Najprostsza metoda wykorzystuje printfi ex:

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

1aoznacza „dołącz po pierwszej linii”; .kończy dołączanie; xoznacza zapisz i wyjdź.

Dzika karta
źródło
0

Żadna z powyższych odpowiedzi nie wspomina o tym, jak zapisać zmiany w oryginalnym pliku, czyli myślę, że o to poprosił OP.

Z pewnością tego potrzebowałem, kiedy przechodziłem do strony.

Zakładając, że plik się nazywa output.txt

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

Moim szczególnym przypadkiem użycia jest automatyczne dodanie deklaracji arkusza stylów xsl do pliku xun junita.

sed -i '1 a <?xml-stylesheet type="text/xsl" href="junit-html.xsl"?>' junit.xml
chim
źródło
yourownlinux.com/2015/04/… jest odpowiednią częścią dobrze napisanego wstępu do sed.
Chim