2012-04-02 20 views
7

AKTUALIZACJA:sed wstawić na pierwszy mecz tylko

Korzystanie sed, jak mogę wstawić (a nie zastępować) nową linię tylko na pierwszy mecz z kluczowych dla każdego pliku.

Obecnie mam następujący ale ta wstawia do każdego wiersza zawierającego kluczowe dopasowane i chcę go tylko wstawić nowy wstawionej linii tylko w pierwszym meczu znaleziony w pliku:

sed -ie '/Matched Keyword/ i\New Inserted Line' *.* 

Na przykład:

myfile.txt:

Line 1 
Line 2 
Line 3 
This line contains the Matched Keyword and other stuff 
Line 4 
This line contains the Matched Keyword and other stuff 
Line 6 

zmienione na:

Line 1 
Line 2 
Line 3 
New Inserted Line 
This line contains the Matched Keyword and other stuff 
Line 4 
This line contains the Matched Keyword and other stuff 
Line 6 
+0

Możliwy duplikat [to pytanie] (http: // przepełnienie stosu.com/q/148451/1086804) - możesz go dostosować za pomocą linii nowej i odsyłaczy wstecz. Zobacz także [ten przewodnik sed] (http://www.linuxtopia.org/online_books/linux_tool_guides/the_sed_faq/sedfaq4_004.html) –

Odpowiedz

8

Jeśli chcesz jeden z sed *:

sed '0,/Matched Keyword/s//Matched Keyword\nNew Inserted Line/' myfile.txt 

* działa tylko z GNU sed

+1

To nic dla mnie nie robi. – Graham

+4

Ach, twoje rozwiązanie jest najwyraźniej specyficzne dla GNU sed. Chociaż nadal jest nie tak, niestety. – Graham

+0

Działa dla mnie z 'GNU sed wersja 4.2.1'. @Squazic, może chcesz zakwalifikować swoją odpowiedź. Powodzenia wszystkim. – shellter

8

rodzaju Można to zrobić w GNU sed:

sed '0,/Matched Keyword/s//New Inserted Line\n&/' 

Ale to nie jest przenośny . Od przenośność jest dobre, to jest tutaj w awk:

awk '/Matched Keyword/ && !x {print "Text line to insert"; x=1} 1' inputFile 

Albo, jeśli chcesz przekazać zmienną do wydrukowania:

awk -v "var=$var" '/Matched Keyword/ && !x {print var; x=1} 1' inputFile 

Są zarówno wstawić linię tekstu przed pierwszego wystąpienia słowo kluczowe, na linii samodzielnie, na twój przykład.

Pamiętaj, że zarówno słowo sed, jak i awk, dopasowane słowo kluczowe jest wyrażeniem regularnym, a nie tylko słowem kluczowym.

UPDATE:

Ponieważ kwestia ta jest również oznaczone , oto proste rozwiązanie, które jest czystą bash i nie wymagało sed:

#!/bin/bash 

n=0 
while read line; do 
    if [[ "$line" =~ 'Matched Keyword' && $n = 0 ]]; then 
    echo "New Inserted Line" 
    n=1 
    fi 
    echo "$line" 
done 

W obecnej formie, to jak rura . Zamiast tego można go łatwo zawinąć w coś, co działa na pliki.

+0

Czy nie ma sposobu, aby to zrobić w tradycyjnym sed? – Graham

+0

Możliwe jest zaadaptowanie rozwiązania potong dla non-GNU sed. Ale nie będzie to jeden liniowiec. Zwykle robię tylko jednoosobowe sed. :-) – ghoti

+0

+1 Działa wspaniale z awk! Dzięki –

2

To może pracować dla Ciebie:

sed -i -e '/Matched Keyword/{i\New Inserted Line' -e ':a;$q;n;ba;}' *.* 

Jesteś prawie tam! Po prostu stwórz pętlę do odczytu z Matched Keyword na końcu pliku.

+0

ummm, tak, możesz podać w pełni działający przykład, ponieważ nie jestem pewien, jak utworzyć tę "pętlę" w wyrażeniu sed oneline. – johnnyB

+0

@johnnyB, aby utworzyć "pętlę", użyj następujących czterech poleceń: ': a' uchwyt miejsca na pętlę,' $ q', gdy koniec pliku zostanie zaatakowany zakończ (druk ostatniego wiersza), 'n' wydrukuje bieżącą linię i następnie przeczytaj w następnym i 'ba' przerwie (goto) do właściciela miejsca w tym przypadku' a'. – potong

0

Jeśli chcesz dołączyć wiersz po pierwszym meczu, używanie AWK zamiast SED jak poniżej

awk '{print} /Matched Keyword/ && !n {print "New Inserted Line"; n++}' myfile.txt 

wyjściowa:

Line 1 
Line 2 
Line 3 
This line contains the Matched Keyword and other stuff 
New Inserted Line 
Line 4 
This line contains the Matched Keyword and other stuff 
Line 6 
+0

i jak to zrobić w miejscu? – sloven