2013-08-16 12 views
27

Piszę skrypt, który będzie wymagał dodania wierszy w określonej części pliku konfiguracyjnego. Na przykładBash: Wstawianie wiersza do pliku w określonej lokalizacji

Przed:

ServerActors=IpServer.UdpServerUplink MasterServerAddress=unreal.epicgames.com MasterServerPort=27900 
ServerActors=IpServer.UdpServerUplink MasterServerAddress=master0.gamespy.com MasterServerPort=27900 
ServerActors=IpServer.UdpServerUplink MasterServerAddress=master.mplayer.com MasterServerPort=27900 
ServerActors=UWeb.WebServer 

Po:

ServerActors=IpServer.UdpServerUplink MasterServerAddress=unreal.epicgames.com MasterServerPort=27900 
ServerActors=IpServer.UdpServerUplink MasterServerAddress=master0.gamespy.com MasterServerPort=27900 
ServerActors=IpServer.UdpServerUplink MasterServerAddress=master.mplayer.com MasterServerPort=27900 
ServerActors=IpServer.UdpServerUplink MasterServerAddress=master.qtracker.com MasterServerPort=27900 
ServerActors=UWeb.WebServer 

Jak widać jest nowa linia dodaje. W jaki sposób mój skrypt bash może wstawić linię? Zgaduję, że będę musiał użyć sed.

+0

Istnieje wiele sposobów i języki to zrobić, prawdopodobnie 'awk' i' sed' są najlepszymi. Powinieneś wskazać logikę w tych dodatkach, abyśmy mogli pomóc w rozwiązaniu tego problemu. – fedorqui

+0

Trudno jest wywnioskować regułę z jednego skomplikowanego przypadku. Czy chcesz wstawić 'ServerActors = IpServer.UdpServerUplink MasterServerAddress = master.qtracker.com MasterServerPort = 27900' powyżej każdej wzmianki o' WebServer'? Lub postępuj zgodnie z każdą linią 'mplayer' z odpowiednią linią' qtracker' lub co? – Beta

+0

Myślę, że znalazłem odpowiedź. Nie jestem pewien, czy istnieje lepszy sposób. Ale po prostu wprowadziłem do sed linię mplayera z linią mplayera * newline * qtracker line 'sed -i 's/ServerActors = IpServer.UdpServerUplink MasterServerAddress = master.mplayer.com MasterServerPort = 27900/ServerActors = IpServer.UdpServerUplink MasterServerAddress = master.mplayer.com MasterServerPort = 27900 \ nServerAktory = IpServer.UdpServerUplink MasterServerAddress = master.qtracker.com MasterServerPort = 27900/g '/ tmp/test' Jest trochę za długi, ale wydaje się działać. – dgibbs

Odpowiedz

67

Jeśli chcesz dodać wiersz po określonym meczu strun:

$ awk '/master.mplayer.com/ { print; print "new line"; next }1' foo.input 
ServerActors=IpServer.UdpServerUplink MasterServerAddress=unreal.epicgames.com MasterServerPort=27900 
ServerActors=IpServer.UdpServerUplink MasterServerAddress=master0.gamespy.com MasterServerPort=27900 
ServerActors=IpServer.UdpServerUplink MasterServerAddress=master.mplayer.com MasterServerPort=27900 
new line 
ServerActors=UWeb.WebServer 
+3

Zastanawiam się, dlaczego nie uzyskałem więcej głosów, jest to bardziej dynamiczny sposób obsługi rozwiązania niż wyraźne poznanie numeru wiersza, w którym znajduje się wyszukiwany tekst. +1 ode mnie – sadmicrowave

+1

To jest lepsza odpowiedź niż zaakceptował jeden, ponieważ będzie niezawodnie trwał, nawet jeśli coś innego wejdzie w interakcję z danym plikiem, np. byłem usi W tym celu na kompilacji Dockera kontenera nginx i jeśli ktoś miałby dodać do niej jakiś config, zaakceptowana odpowiedź przerwałaby kompilację. To nie będzie. – samtresler

+0

Dlaczego nie działa on z powrotem do tego samego pliku? 'awk ... foo.input> foo.input' po prostu opróżnia ten plik –

25

Można użyć coś takiego:

pamiętać, że polecenie musi być wpisane przez wiele linii, ponieważ sed nie pozwala kodowania nowej linii z „\ n” lub Ctrl-V/Ctrl-M kombinacji klawiszy jak niektóre narzędzia. Odwrotny ukośnik mówi "Ignoruj ​​moje uderzenie w klawisz powrotu, jeszcze nie skończyłem z moim rozkazem".

sed -i.bak '4i\ 
This is the new line\ 
' filename 

To powinno wystarczyć (wstawi to między wierszami 3 i 4).

Jeśli chcesz umieścić to polecenie w skrypcie powłoki, musisz uciec od ukośników, aby nie zostały zjedzone przez bash i nie zostały przekazane do sed. Wewnątrz skryptu, komenda staje:

sed -i.bak '4i\\ 
This is the new line\\ 
' filename 
+0

Widzę, że określasz numer wiersza – dgibbs

+0

Tak, w ten sposób możesz wskazać dokładnie miejsce, w którym chcesz dodać linię. – MPrazz

+0

Inną opcją sed podobną do powyższej byłoby sed '3a \ To jest nowa linia' plik – user1502952

11
awk 'NR==5{print "new line text"}7' file 
+3

przykro mi, dla co to jest "7" tutaj? ('..."} 7') – setevoy

+1

@setevoy to zastosuje domyślną akcję awk: print. – Kent

+0

zostanie zaalokowane, ponieważ ....? – Kent

1

można dodać go sed w pliku filename po pewien ciąg pattern mecz z:

sed '/pattern/a some text here' filename 

w przykładzie

sed '/master.mplayer.com/a \ new line' filename 

(Maski odwrotnego ukośnika pierwsze miejsca w nowej linii, więc można dodać więcej spacji na początku)

źródło: https://unix.stackexchange.com/a/121166/20661

Powiązane problemy