2011-11-17 20 views
8

ja po prostu chcę zrobić pozastąpienie wielu wzór linii w sed

zastąpić

EXTRATHING { 
}; 

przez

SOMETHING {}; 

w pliku wejściowym. W tym celu wypróbowałem:

sed -e 's/EXTRATHING {\n};/SOMETHING/' input_file.txt >outfile.txt 

To nie działa. Czy ktoś może zasugerować, jaki byłby właściwy sposób robienia tego z sed?

Odpowiedz

5
sed -n '1h;1!H;${;g;s/EXTRATHING {\n};/SOMETHING {};/g;p;}' input_file.txt 

zrobi to.

Problem polega na tym, że przechowuje cały łańcuch wejściowy w buforze sed.

Aby uzyskać więcej informacji i bardziej wydajną wersję, zobacz artykuł sed and Multi-Line Search and Replace.

0

To może pracować dla Ciebie:

sed '/^EXTRATHING {/,/^};/c\SOMETHING{}' input_file.txt >output_file.txt 

lub jeśli chcesz edytować oryginalny plik:

sed -i '/^EXTRATHING {/,/^};/c\SOMETHING{}' input_file 

EDIT: jak żądany oto przykład:

cat <<! | sed '/^EXTRATHING {/,/^};/c\SOMETHING{}' 
> aaa 
> EXTRATHING { 
> }; 
> bbb 
> EXTRATHING { 
> }; 
> ccc 
> ! 
aaa 
SOMETHING{} 
bbb 
SOMETHING{} 
ccc 

EDIT : Jeśli pierwszy i ostatni adres są kolejnymi liniami, użyj tego:

# cat <<\! | sed '/^EXTRATHING {/{N;s/^EXTRATHING {\n};/SOMETHING{}/}' 
> aaa 
> EXTRATHING { 
> bbb 
> }; 
> ccc 
> EXTRATHING { 
> }; 
> ddd 
> ! 
aaa 
EXTRATHING { 
bbb 
}; 
ccc 
SOMETHING{} 
ddd 

Innym sposobem (być może łatwiej?):

echo -e "EXTRATHING {\n};" | sed '$!N;s/^EXTRATHING {\n};/SOMETHING {};/;P;D' 
SOMETHING {}; 
+0

zadbać o opublikowanie przykładu, że to działa ;-)? Właśnie otrzymałem oryginalny dokument wrócił ... Powodzenia. – shellter

+0

Dzięki @potong. Jednak twoje polecenie usunie również oryginalny wzór, jeśli istnieją inne linie między "EXTRATHING {" i "};". Nie chcę ich zastępować.Tak więc nie należy zastępować następujących elementów "EXTRATHING {\ n something \ n};". – bbv

+0

Dzięki, widzę twój kod działa z sed 4 *, ale nie z wersją bez wersji, którą mam w UWIN. Czy używasz wyrażenia zasięgu do przechwytywania dwóch linii? tj. '/ x /,/y /'? Powodzenia wszystkim. – shellter

3

sed -e '/begin/,/end/{s/begin/replacement/p;d}'

+4

Czy możesz to wyjaśnić? Dzięki. :) – Ray

+1

Myślę, że było to oparte na złym rozumieniu tego pytania. – BCS

3
sed -i.bak '/EXTRATHING/{N;s//SOMETHING/;s/\n//}' input_file.txt 
1
perl -lne 's/\s*};\s*$/SOMETHING{};/g if(/\s*};\s*$/);$f=0;if(/EXTRATHING {\s*$/){next;$f=1}else{print}' your_file 

testowane poniżej:

> cat temp 
fjbwjfbw 
wefjkbwjk 
jbefwejr 
EXTRATHING { 
}; 
ghekg 
jhgjk 
wefjkwngk 
EXTRATHING { 
    }; 
jbgvjnrg 
jbfw 
wefnkwk 
EXTRATHING { 
}; 
> perl -lne 's/\s*};\s*$/SOMETHING{};/g if(/\s*};\s*$/);$f=0;if(/EXTRATHING {\s*$/){next;$f=1}else{print}' temp 
fjbwjfbw 
wefjkbwjk 
jbefwejr 
SOMETHING{}; 
ghekg 
jhgjk 
wefjkwngk 
SOMETHING{}; 
jbgvjnrg 
jbfw 
wefnkwk 
SOMETHING{}; 
> 

jeśli chcesz zmienić inline pliku . dodaj flagę -i. jak:

perl -i -lne '.......' your_file 
0

Jego trudno to zrobić w sed, musi napisać indeksów. Jednakże, można użyć jednego-liner przy użyciu Perl:

perl -0777 -pe 's/EXTRATHING {\n/SOMETHING {/g' input_file.txt > outfile.txt 

gdzie -0777 jest rekord separator (wiersz_końca w plikach tekstowych) -p uruchamia polecenie dla wszystkich plików i wydruków na ekranie -e mówi jej jedną polecenie linii

Powiązane problemy